From rhettinger@users.sourceforge.net Sat Feb 1 00:10:12 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 31 Jan 2003 16:10:12 -0800 Subject: [Python-checkins] python/dist/src/Modules itertoolsmodule.c,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv25990/Modules Added Files: itertoolsmodule.c Log Message: Move itertools module from the sandbox and into production. --- NEW FILE: itertoolsmodule.c --- #include "Python.h" /* Itertools module written and maintained by Raymond D. Hettinger Copyright (c) 2003 Python Software Foundation. All rights reserved. */ /* dropwhile object **********************************************************/ typedef struct { PyObject_HEAD PyObject *func; PyObject *it; long start; } dropwhileobject; PyTypeObject dropwhile_type; [...1493 lines suppressed...] if (PyType_Ready(&ifilter_type) < 0) return; Py_INCREF(&ifilter_type); PyModule_AddObject(m, "ifilter", (PyObject *)&ifilter_type); if (PyType_Ready(&count_type) < 0) return; Py_INCREF(&count_type); PyModule_AddObject(m, "count", (PyObject *)&count_type); if (PyType_Ready(&izip_type) < 0) return; Py_INCREF(&izip_type); PyModule_AddObject(m, "izip", (PyObject *)&izip_type); if (PyType_Ready(&repeat_type) < 0) return; Py_INCREF(&repeat_type); PyModule_AddObject(m, "repeat", (PyObject *)&repeat_type); } From rhettinger@users.sourceforge.net Sat Feb 1 00:10:12 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 31 Jan 2003 16:10:12 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.633,1.634 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv25990/Misc Modified Files: NEWS Log Message: Move itertools module from the sandbox and into production. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.633 retrieving revision 1.634 diff -C2 -d -r1.633 -r1.634 *** NEWS 31 Jan 2003 22:27:15 -0000 1.633 --- NEWS 1 Feb 2003 00:10:09 -0000 1.634 *************** *** 31,34 **** --- 31,37 ---- ----------------- + - Added an itertools module containing high speed, memory efficient + looping constructs inspired by tools from Haskell and SML. + - The SSL module now handles sockets with a timeout set correctly (SF patch #675750, fixing SF bug #675552). From rhettinger@users.sourceforge.net Sat Feb 1 00:10:13 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 31 Jan 2003 16:10:13 -0800 Subject: [Python-checkins] python/dist/src/PC config.c,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory sc8-pr-cvs1:/tmp/cvs-serv25990/PC Modified Files: config.c Log Message: Move itertools module from the sandbox and into production. Index: config.c =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/config.c,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** config.c 30 Dec 2002 22:08:04 -0000 1.37 --- config.c 1 Feb 2003 00:10:10 -0000 1.38 *************** *** 46,49 **** --- 46,50 ---- extern void initzipimport(void); extern void init_random(void); + extern void inititertools(void); /* XXX tim: what's the purpose of ADDMODULE MARKER? */ *************** *** 98,101 **** --- 99,103 ---- {"_hotshot", init_hotshot}, {"_random", init_random}, + {"itertools", inititertools}, {"xxsubtype", initxxsubtype}, From rhettinger@users.sourceforge.net Sat Feb 1 00:10:11 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 31 Jan 2003 16:10:11 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libitertools.tex,NONE,1.1 lib.tex,1.213,1.214 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv25990/Doc/lib Modified Files: lib.tex Added Files: libitertools.tex Log Message: Move itertools module from the sandbox and into production. --- NEW FILE: libitertools.tex --- \section{\module{itertools} --- Functions creating iterators for efficient looping} \declaremodule{standard}{itertools} \modulesynopsis{Functions creating iterators for efficient looping.} \moduleauthor{Raymond Hettinger}{python@rcn.com} \sectionauthor{Raymond Hettinger}{python@rcn.com} \versionadded{2.3} This module implements a number of iterator building blocks inspired by constructs from the Haskell and SML programming languages. Each has been recast in a form suitable for Python. With the advent of iterators and generators in Python 2.3, each of these tools can be expressed easily and succinctly in pure python. Rather duplicating what can already be done, this module emphasizes providing value in other ways: \begin{itemize} \item Instead of constructing an over-specialized toolset, this module provides basic building blocks that can be readily combined. For instance, SML provides a tabulation tool: \code{tabulate(\var{f})} which produces a sequence \code{f(0), f(1), ...}. This toolbox takes a different approach of providing \function{imap()} and \function{count()} which can be combined to form \code{imap(\var{f}, count())} and produce an equivalent result. \item Some tools were dropped because they offer no advantage over their pure python counterparts or because their behavior was too surprising. For instance, SML provides a tool: \code{cycle(\var{seq})} which loops over the sequence elements and then starts again when the sequence is exhausted. The surprising behavior is the need for significant auxiliary storage (unusual for iterators). Also, it is trivially implemented in python with almost no performance penalty. \item Another source of value comes from standardizing a core set of tools to avoid the readability and reliability problems that arise when many different individuals create their own slightly varying implementations each with their own quirks and naming conventions. \item Whether cast in pure python form or C code, tools that use iterators are more memory efficient (and faster) than their list based counterparts. Adopting the principles of just-in-time manufacturing, they create data when and where needed instead of consuming memory with the computer equivalent of ``inventory''. \end{itemize} \begin{seealso} \seetext{The Standard ML Basis Library, \citetitle[http://www.standardml.org/Basis/] {The Standard ML Basis Library}.} \seetext{Haskell, A Purely Functional Language, \citetitle[http://www.haskell.org/definition/] {Definition of Haskell and the Standard Libraries}.} \end{seealso} \subsection{Itertool functions \label{itertools-functions}} The following module functions all construct and return iterators. Some provide streams of infinite length, so they should only be accessed by functions or loops that truncate the stream. \begin{funcdesc}{count}{\optional{n}} Make an iterator that returns consecutive integers starting with \var{n}. Does not currently support python long integers. Often used as an argument to \function{imap()} to generate consecutive data points. Also, used in \function{izip()} to add sequence numbers. Equivalent to: \begin{verbatim} def count(n=0): cnt = n while True: yield cnt cnt += 1 \end{verbatim} \end{funcdesc} \begin{funcdesc}{dropwhile}{predicate, iterable} Make an iterator that drops elements from the iterable as long as the predicate is true; afterwards, returns every element. Note, the iterator does not produce \emph{any} output until the predicate is true, so it may have a lengthy start-up time. Equivalent to: \begin{verbatim} def dropwhile(predicate, iterable): iterable = iter(iterable) while True: x = iterable.next() if predicate(x): continue # drop when predicate is true yield x break while True: yield iterable.next() \end{verbatim} \end{funcdesc} \begin{funcdesc}{ifilter}{predicate, iterable \optional{, invert}} Make an iterator that filters elements from iterable returning only those for which the predicate is \code{True}. If \var{invert} is \code{True}, then reverse the process and pass through only those elements for which the predicate is \code{False}. If \var{predicate} is \code{None}, return the items that are true (or false if \var{invert} has been set). Equivalent to: \begin{verbatim} def ifilter(predicate, iterable, invert=False): iterable = iter(iterable) while True: x = iterable.next() if predicate is None: b = bool(x) else: b = bool(predicate(x)) if not invert and b or invert and not b: yield x \end{verbatim} \end{funcdesc} \begin{funcdesc}{imap}{function, *iterables} Make an iterator that computes the function using arguments from each of the iterables. If \var{function} is set to \code{None}, then \function{imap()} returns the arguments as a tuple. Like \function{map()} but stops when the shortest iterable is exhausted instead of filling in \code{None} for shorter iterables. The reason for the difference is that infinite iterator arguments are typically an error for \function{map()} (because the output is fully evaluated) but represent a common and useful way of supplying arguments to \function{imap()}. Equivalent to: \begin{verbatim} def imap(function, *iterables): iterables = map(iter, iterables) while True: args = [i.next() for i in iterables] if function is None: yield tuple(args) else: yield function(*args) \end{verbatim} \end{funcdesc} \begin{funcdesc}{islice}{iterable, \optional{start,} stop \optional{, step}} Make an iterator that returns selected elements from the iterable. If \var{start} is non-zero, then elements from the iterable are skipped until start is reached. Afterward, elements are returned consecutively unless \var{step} is set higher than one which results in items being skipped. If \var{stop} is specified, then iteration stops at the specified element position; otherwise, it continues indefinitely or until the iterable is exhausted. Unlike regular slicing, \function{islice()} does not support negative values for \var{start}, \var{stop}, or \var{step}. Can be used to extract related fields from data where the internal structure has been flattened (for example, a multi-line report may list a name field on every third line). Equivalent to: \begin{verbatim} def islice(iterable, *args): iterable = iter(iterable) s = slice(*args) next = s.start or 0 stop = s.stop step = s.step or 1 cnt = 0 while True: while cnt < next: dummy = iterable.next() cnt += 1 if cnt >= stop: break yield iterable.next() cnt += 1 next += step \end{verbatim} \end{funcdesc} \begin{funcdesc}{izip}{*iterables} Make an iterator that aggregates elements from each of the iterables. Like \function{zip()} except that it returns an iterator instead of a list. Used for lock-step iteration over several iterables at a time. Equivalent to: \begin{verbatim} def izip(*iterables): iterables = map(iter, iterables) while True: result = [i.next() for i in iterables] yield tuple(result) \end{verbatim} \end{funcdesc} \begin{funcdesc}{repeat}{obj} Make an iterator that returns \var{obj} over and over again. Used as argument to \function{imap()} for invariant parameters to the called function. Also used with function{izip()} to create an invariant part of a tuple record. Equivalent to: \begin{verbatim} def repeat(x): while True: yield x \end{verbatim} \end{funcdesc} \begin{funcdesc}{starmap}{function, iterable} Make an iterator that computes the function using arguments tuples obtained from the iterable. Used instead of \function{imap()} when argument parameters are already grouped in tuples from a single iterable (the data has been ``pre-zipped''). The difference between \function{imap()} and \function{starmap} parallels the distinction between \code{function(a,b)} and \code{function(*c)}. Equivalent to: \begin{verbatim} def starmap(function, iterable): iterable = iter(iterable) while True: yield function(*iterable.next()) \end{verbatim} \end{funcdesc} \begin{funcdesc}{takewhile}{predicate, iterable} Make an iterator that returns elements from the iterable as long as the predicate is true. Equivalent to: \begin{verbatim} def takewhile(predicate, iterable): iterable = iter(iterable) while True: x = iterable.next() if predicate(x): yield x else: break \end{verbatim} \end{funcdesc} \begin{funcdesc}{times}{n, \optional{object}} Make an iterator that returns \var{object} \var{n} times. \var{object} defaults to \code{None}. Used for looping a specific number of times without creating a number object on each pass. Equivalent to: \begin{verbatim} def times(n, object=None): if n<0 : raise ValueError for i in xrange(n): yield object \end{verbatim} \end{funcdesc} \subsection{Examples \label{itertools-example}} The following examples show common uses for each tool and demonstrate ways they can be combined. \begin{verbatim} >>> for i in times(3): ... print "Hello" ... Hello Hello Hello >>> amounts = [120.15, 764.05, 823.14] >>> for checknum, amount in izip(count(1200), amounts): ... print 'Check %d is for $%.2f' % (checknum, amount) ... Check 1200 is for $120.15 Check 1201 is for $764.05 Check 1202 is for $823.14 >>> import operator >>> for cube in imap(operator.pow, xrange(1,4), repeat(3)): ... print cube ... 1 8 27 >>> reportlines = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'samuele'] >>> for name in islice(reportlines, 3, len(reportlines), 2): ... print name.title() ... Alex Laura Martin Walter Samuele \end{verbatim} This section has further examples of how itertools can be combined. Note that \function{enumerate()} and \method{iteritems()} already have highly efficient implementations in Python. They are only included here to illustrate how higher level tools can be created from building blocks. \begin{verbatim} >>> def enumerate(iterable): ... return izip(count(), iterable) >>> def tabulate(function): ... "Return function(0), function(1), ..." ... return imap(function, count()) >>> def iteritems(mapping): ... return izip(mapping.iterkeys(), mapping.itervalues()) >>> def nth(iterable, n): ... "Returns the nth item" ... return islice(iterable, n, n+1).next() \end{verbatim} Index: lib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/lib.tex,v retrieving revision 1.213 retrieving revision 1.214 diff -C2 -d -r1.213 -r1.214 *** lib.tex 7 Jan 2003 22:36:04 -0000 1.213 --- lib.tex 1 Feb 2003 00:10:09 -0000 1.214 *************** *** 126,129 **** --- 126,130 ---- \input{libarray} \input{libsets} + \input{libitertools} \input{libcfgparser} \input{libfileinput} From rhettinger@users.sourceforge.net Sat Feb 1 00:10:11 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 31 Jan 2003 16:10:11 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_itertools.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv25990/Lib/test Added Files: test_itertools.py Log Message: Move itertools module from the sandbox and into production. --- NEW FILE: test_itertools.py --- import unittest from test import test_support from itertools import * class TestBasicOps(unittest.TestCase): def test_count(self): self.assertEqual(zip('abc',count()), [('a', 0), ('b', 1), ('c', 2)]) self.assertEqual(zip('abc',count(3)), [('a', 3), ('b', 4), ('c', 5)]) self.assertRaises(TypeError, count, 2, 3) def test_ifilter(self): def isEven(x): return x%2==0 self.assertEqual(list(ifilter(isEven, range(6))), [0,2,4]) self.assertEqual(list(ifilter(isEven, range(6), True)), [1,3,5]) self.assertEqual(list(ifilter(None, [0,1,0,2,0])), [1,2]) self.assertRaises(TypeError, ifilter) self.assertRaises(TypeError, ifilter, 3) self.assertRaises(TypeError, ifilter, isEven, 3) self.assertRaises(TypeError, ifilter, isEven, [3], True, 4) def test_izip(self): ans = [(x,y) for x, y in izip('abc',count())] self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)]) self.assertRaises(TypeError, izip) def test_repeat(self): self.assertEqual(zip(xrange(3),repeat('a')), [(0, 'a'), (1, 'a'), (2, 'a')]) self.assertRaises(TypeError, repeat) def test_times(self): self.assertEqual(list(times(3)), [None]*3) self.assertEqual(list(times(3, True)), [True]*3) self.assertRaises(ValueError, times, -1) def test_imap(self): import operator self.assertEqual(list(imap(operator.pow, range(3), range(1,7))), [0**1, 1**2, 2**3]) self.assertEqual(list(imap(None, 'abc', range(5))), [('a',0),('b',1),('c',2)]) self.assertRaises(TypeError, imap) self.assertRaises(TypeError, imap, operator.neg) def test_starmap(self): import operator self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))), [0**1, 1**2, 2**3]) def test_islice(self): for args in [ # islice(args) should agree with range(args) (10, 20, 3), (10, 3, 20), (10, 20), (10, 3), (20,) ]: self.assertEqual(list(islice(xrange(100), *args)), range(*args)) for args, tgtargs in [ # Stop when seqn is exhausted ((10, 110, 3), ((10, 100, 3))), ((10, 110), ((10, 100))), ((110,), (100,)) ]: self.assertEqual(list(islice(xrange(100), *args)), range(*tgtargs)) self.assertRaises(TypeError, islice, xrange(10)) self.assertRaises(TypeError, islice, xrange(10), 1, 2, 3, 4) self.assertRaises(ValueError, islice, xrange(10), -5, 10, 1) self.assertRaises(ValueError, islice, xrange(10), 1, -5, -1) self.assertRaises(ValueError, islice, xrange(10), 1, 10, -1) self.assertRaises(ValueError, islice, xrange(10), 1, 10, 0) def test_takewhile(self): data = [1, 3, 5, 20, 2, 4, 6, 8] underten = lambda x: x<10 self.assertEqual(list(takewhile(underten, data)), [1, 3, 5]) def test_dropwhile(self): data = [1, 3, 5, 20, 2, 4, 6, 8] underten = lambda x: x<10 self.assertEqual(list(dropwhile(underten, data)), [20, 2, 4, 6, 8]) libreftest = """ Doctest for examples in the library reference, libitertools.tex >>> for i in times(3): ... print "Hello" ... Hello Hello Hello >>> amounts = [120.15, 764.05, 823.14] >>> for checknum, amount in izip(count(1200), amounts): ... print 'Check %d is for $%.2f' % (checknum, amount) ... Check 1200 is for $120.15 Check 1201 is for $764.05 Check 1202 is for $823.14 >>> import operator >>> import operator >>> for cube in imap(operator.pow, xrange(1,4), repeat(3)): ... print cube ... 1 8 27 >>> reportlines = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'samuele'] >>> for name in islice(reportlines, 3, len(reportlines), 2): ... print name.title() ... Alex Laura Martin Walter Samuele >>> def enumerate(iterable): ... return izip(count(), iterable) >>> def tabulate(function): ... "Return function(0), function(1), ..." ... return imap(function, count()) >>> def iteritems(mapping): ... return izip(mapping.iterkeys(), mapping.itervalues()) >>> def nth(iterable, n): ... "Returns the nth item" ... return islice(iterable, n, n+1).next() """ __test__ = {'libreftest' : libreftest} def test_main(verbose=None): import test_itertools suite = unittest.TestSuite() for testclass in (TestBasicOps, ): suite.addTest(unittest.makeSuite(testclass)) test_support.run_suite(suite) test_support.run_doctest(test_itertools, verbose) # verify reference counting import sys if verbose and hasattr(sys, "gettotalrefcount"): counts = [] for i in xrange(5): test_support.run_suite(suite) counts.append(sys.gettotalrefcount()) print counts if __name__ == "__main__": test_main(verbose=True) From rhettinger@users.sourceforge.net Sat Feb 1 00:10:13 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 31 Jan 2003 16:10:13 -0800 Subject: [Python-checkins] python/dist/src/PCbuild pythoncore.dsp,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory sc8-pr-cvs1:/tmp/cvs-serv25990/PCbuild Modified Files: pythoncore.dsp Log Message: Move itertools module from the sandbox and into production. Index: pythoncore.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pythoncore.dsp,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** pythoncore.dsp 31 Dec 2002 02:09:08 -0000 1.41 --- pythoncore.dsp 1 Feb 2003 00:10:11 -0000 1.42 *************** *** 324,327 **** --- 324,331 ---- # Begin Source File + SOURCE=..\Modules\itertoolsmodule.c + # End Source File + # Begin Source File + SOURCE=..\Parser\listnode.c # End Source File From rhettinger@users.sourceforge.net Sat Feb 1 00:10:41 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 31 Jan 2003 16:10:41 -0800 Subject: [Python-checkins] python/dist/src setup.py,1.139,1.140 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv25990 Modified Files: setup.py Log Message: Move itertools module from the sandbox and into production. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.139 retrieving revision 1.140 diff -C2 -d -r1.139 -r1.140 *** setup.py 29 Jan 2003 03:49:42 -0000 1.139 --- setup.py 1 Feb 2003 00:10:09 -0000 1.140 *************** *** 325,328 **** --- 325,330 ---- # random number generator implemented in C exts.append( Extension("_random", ["_randommodule.c"]) ) + # fast iterator tools implemented in C + exts.append( Extension("itertools", ["itertoolsmodule.c"]) ) # operator.add() and similar goodies exts.append( Extension('operator', ['operator.c']) ) From tim_one@users.sourceforge.net Sat Feb 1 01:47:31 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 17:47:31 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.51,1.52 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv5895/Modules Modified Files: datetimemodule.c Log Message: delta_setstate(): This waS no longer referenced, so nukeit. delta_reduce(): Simplified. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.51 retrieving revision 1.52 diff -C2 -d -r1.51 -r1.52 *** datetimemodule.c 31 Jan 2003 22:27:17 -0000 1.51 --- datetimemodule.c 1 Feb 2003 01:47:29 -0000 1.52 *************** *** 1948,1954 **** } ! /* Pickle support. Quite a maze! While __getstate__/__setstate__ sufficed ! * in the Python implementation, the C implementation also requires ! * __reduce__, and a __safe_for_unpickling__ attr in the type object. */ static PyObject * --- 1948,1952 ---- } ! /* Pickle support. This is a plain application of __reduce__. */ static PyObject * *************** *** 1960,2001 **** } - /* __setstate__ isn't exposed. */ - static PyObject * - delta_setstate(PyDateTime_Delta *self, PyObject *state) - { - int day; - int second; - int us; - - if (!PyArg_ParseTuple(state, "iii:__setstate__", &day, &second, &us)) - return NULL; - - self->hashcode = -1; - SET_TD_DAYS(self, day); - SET_TD_SECONDS(self, second); - SET_TD_MICROSECONDS(self, us); - - Py_INCREF(Py_None); - return Py_None; - } - static PyObject * delta_reduce(PyDateTime_Delta* self) { ! PyObject* result = NULL; ! PyObject* state = delta_getstate(self); ! ! if (state != NULL) { ! /* The funky "()" in the format string creates an empty ! * tuple as the 2nd component of the result 3-tuple. ! */ ! result = Py_BuildValue("O(iii)", ! self->ob_type, ! self->days, ! self->seconds, ! self->microseconds); ! Py_DECREF(state); ! } ! return result; } --- 1958,1965 ---- } static PyObject * delta_reduce(PyDateTime_Delta* self) { ! return Py_BuildValue("ON", self->ob_type, delta_getstate(self)); } From tim_one@users.sourceforge.net Sat Feb 1 01:52:52 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 17:52:52 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.52,1.53 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv7601/Modules Modified Files: datetimemodule.c Log Message: All over: changed comments to reflect pickling is straightforward now, not the maze it was. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -d -r1.52 -r1.53 *** datetimemodule.c 1 Feb 2003 01:47:29 -0000 1.52 --- datetimemodule.c 1 Feb 2003 01:52:50 -0000 1.53 *************** *** 1948,1953 **** } ! /* Pickle support. This is a plain application of __reduce__. ! */ static PyObject * delta_getstate(PyDateTime_Delta *self) --- 1948,1953 ---- } ! /* Pickle support, a simple use of __reduce__. */ ! static PyObject * delta_getstate(PyDateTime_Delta *self) *************** *** 2524,2528 **** } ! /* Pickle support. Quite a maze! */ static PyObject * --- 2524,2528 ---- } ! /* Pickle support, a simple use of __reduce__. */ static PyObject * *************** *** 3336,3342 **** } ! /* ! * Pickle support. Quite a maze! ! */ /* Let basestate be the non-tzinfo data string. --- 3336,3340 ---- } ! /* Pickle support, a simple use of __reduce__. */ /* Let basestate be the non-tzinfo data string. *************** *** 4338,4342 **** } ! /* Pickle support. Quite a maze! */ /* Let basestate be the non-tzinfo data string. --- 4336,4340 ---- } ! /* Pickle support, a simple use of __reduce__. */ /* Let basestate be the non-tzinfo data string. From tim_one@users.sourceforge.net Sat Feb 1 02:16:39 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 18:16:39 -0800 Subject: [Python-checkins] python/dist/src/Lib copy_reg.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv14164/Lib Modified Files: copy_reg.py Log Message: Removed all uses of the out-of-favor __safe_for_unpickling__ magic attr, and copy_reg.safe_constructors. Index: copy_reg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy_reg.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** copy_reg.py 31 Jan 2003 20:34:07 -0000 1.12 --- copy_reg.py 1 Feb 2003 02:16:36 -0000 1.13 *************** *** 11,15 **** dispatch_table = {} - safe_constructors = {} def pickle(ob_type, pickle_function, constructor_ob=None): --- 11,14 ---- *************** *** 27,31 **** if not callable(object): raise TypeError("constructors must be callable") - safe_constructors[object] = 1 # Example: provide pickling support for complex numbers. --- 26,29 ---- *************** *** 42,46 **** base.__init__(obj, state) return obj - _reconstructor.__safe_for_unpickling__ = 1 _HEAPTYPE = 1<<9 --- 40,43 ---- From tim_one@users.sourceforge.net Sat Feb 1 02:16:39 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 18:16:39 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.30,1.31 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv14164/Lib/test Modified Files: pickletester.py Log Message: Removed all uses of the out-of-favor __safe_for_unpickling__ magic attr, and copy_reg.safe_constructors. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** pickletester.py 29 Jan 2003 17:58:44 -0000 1.30 --- pickletester.py 1 Feb 2003 02:16:36 -0000 1.31 *************** *** 16,21 **** class initarg(C): - __safe_for_unpickling__ = 1 - def __init__(self, a, b): self.a = a --- 16,19 ---- From tim_one@users.sourceforge.net Sat Feb 1 02:16:39 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 18:16:39 -0800 Subject: [Python-checkins] python/dist/src/Objects structseq.c,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv14164/Objects Modified Files: structseq.c Log Message: Removed all uses of the out-of-favor __safe_for_unpickling__ magic attr, and copy_reg.safe_constructors. Index: structseq.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/structseq.c,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** structseq.c 18 Dec 2002 23:20:39 -0000 1.11 --- structseq.c 1 Feb 2003 02:16:37 -0000 1.12 *************** *** 393,396 **** PyDict_SetItemString(dict, unnamed_fields_key, PyInt_FromLong((long) n_unnamed_members)); - PyDict_SetItemString(dict, "__safe_for_unpickling__", Py_True); } --- 393,395 ---- From tim_one@users.sourceforge.net Sat Feb 1 02:16:39 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 18:16:39 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.100,2.101 datetimemodule.c,1.53,1.54 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv14164/Modules Modified Files: cPickle.c datetimemodule.c Log Message: Removed all uses of the out-of-favor __safe_for_unpickling__ magic attr, and copy_reg.safe_constructors. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.100 retrieving revision 2.101 diff -C2 -d -r2.100 -r2.101 *** cPickle.c 31 Jan 2003 21:10:31 -0000 2.100 --- cPickle.c 1 Feb 2003 02:16:37 -0000 2.101 *************** *** 93,104 **** static PyObject *dispatch_table; - static PyObject *safe_constructors; static PyObject *empty_tuple; static PyObject *__class___str, *__getinitargs___str, *__dict___str, *__getstate___str, *__setstate___str, *__name___str, *__reduce___str, ! *write_str, *__safe_for_unpickling___str, *append_str, *read_str, *readline_str, *__main___str, *__basicnew___str, ! *copy_reg_str, *dispatch_table_str, *safe_constructors_str; /************************************************************************* --- 93,103 ---- static PyObject *dispatch_table; static PyObject *empty_tuple; static PyObject *__class___str, *__getinitargs___str, *__dict___str, *__getstate___str, *__setstate___str, *__name___str, *__reduce___str, ! *write_str, *append_str, *read_str, *readline_str, *__main___str, *__basicnew___str, ! *copy_reg_str, *dispatch_table_str; /************************************************************************* *************** *** 307,311 **** int buf_size; char *buf; - PyObject *safe_constructors; PyObject *find_class; } Unpicklerobject; --- 306,309 ---- *************** *** 3079,3084 **** Instance_New(PyObject *cls, PyObject *args) { ! int has_key; ! PyObject *safe=0, *r=0; if (PyClass_Check(cls)) { --- 3077,3081 ---- Instance_New(PyObject *cls, PyObject *args) { ! PyObject *r = 0; if (PyClass_Check(cls)) { *************** *** 3108,3126 **** } - /* Is safe_constructors always a dict? */ - has_key = cPickle_PyMapping_HasKey(safe_constructors, cls); - if (!has_key) { - safe = PyObject_GetAttr(cls, __safe_for_unpickling___str); - if (!safe || - !PyObject_IsTrue(safe)) { - cPickle_ErrFormat(UnpicklingError, - "%s is not safe for unpickling", - "O", cls); - Py_XDECREF(safe); - return NULL; - } - Py_DECREF(safe); - } - if (args==Py_None) { /* Special case, call cls.__basicnew__() */ --- 3105,3108 ---- *************** *** 4333,4337 **** self->read = NULL; self->readline = NULL; - self->safe_constructors = NULL; self->find_class = NULL; --- 4315,4318 ---- *************** *** 4374,4392 **** } - if (PyEval_GetRestricted()) { - /* Restricted execution, get private tables */ - PyObject *m; - - if (!( m=PyImport_Import(copy_reg_str))) goto err; - self->safe_constructors=PyObject_GetAttr(m, - safe_constructors_str); - Py_DECREF(m); - if (!( self->safe_constructors )) goto err; - } - else { - self->safe_constructors=safe_constructors; - Py_INCREF(safe_constructors); - } - return self; --- 4355,4358 ---- *************** *** 4419,4423 **** Py_XDECREF(self->arg); Py_XDECREF(self->last_string); - Py_XDECREF(self->safe_constructors); if (self->marks) { --- 4385,4388 ---- *************** *** 4694,4698 **** INIT_STR(__reduce__); INIT_STR(write); - INIT_STR(__safe_for_unpickling__); INIT_STR(append); INIT_STR(read); --- 4659,4662 ---- *************** *** 4700,4704 **** INIT_STR(copy_reg); INIT_STR(dispatch_table); - INIT_STR(safe_constructors); INIT_STR(__basicnew__); --- 4664,4667 ---- *************** *** 4706,4717 **** return -1; ! /* These next few are special because we want to use different ! ones in restricted mode. */ dispatch_table = PyObject_GetAttr(copy_reg, dispatch_table_str); if (!dispatch_table) - return -1; - - if (!( safe_constructors = PyObject_GetAttr(copy_reg, - safe_constructors_str))) return -1; --- 4669,4676 ---- return -1; ! /* This is special because we want to use a different ! one in restricted mode. */ dispatch_table = PyObject_GetAttr(copy_reg, dispatch_table_str); if (!dispatch_table) return -1; Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -d -r1.53 -r1.54 *** datetimemodule.c 1 Feb 2003 01:52:50 -0000 1.53 --- datetimemodule.c 1 Feb 2003 02:16:37 -0000 1.54 *************** *** 4517,4527 **** PyObject *x; - /* Types that use __reduce__ for pickling need to set the following - * magical attr in the type dict, with a true value. - */ - PyObject *safepickle = PyString_FromString("__safe_for_unpickling__"); - if (safepickle == NULL) - return; - m = Py_InitModule3("datetime", module_methods, "Fast implementation of the datetime type."); --- 4517,4520 ---- *************** *** 4578,4593 **** } - /* tzinfo values */ - d = PyDateTime_TZInfoType.tp_dict; - - if (PyDict_SetItem(d, safepickle, Py_True) < 0) - return; - /* timedelta values */ d = PyDateTime_DeltaType.tp_dict; - if (PyDict_SetItem(d, safepickle, Py_True) < 0) - return; - x = new_delta(0, 0, 1, 0); if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) --- 4571,4577 ---- *************** *** 4608,4614 **** d = PyDateTime_DateType.tp_dict; - if (PyDict_SetItem(d, safepickle, Py_True) < 0) - return; - x = new_date(1, 1, 1); if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) --- 4592,4595 ---- *************** *** 4629,4635 **** d = PyDateTime_TimeType.tp_dict; - if (PyDict_SetItem(d, safepickle, Py_True) < 0) - return; - x = new_time(0, 0, 0, 0, Py_None); if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) --- 4610,4613 ---- *************** *** 4650,4656 **** d = PyDateTime_DateTimeType.tp_dict; - if (PyDict_SetItem(d, safepickle, Py_True) < 0) - return; - x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None); if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) --- 4628,4631 ---- *************** *** 4667,4672 **** return; Py_DECREF(x); - - Py_DECREF(safepickle); /* module initialization */ --- 4642,4645 ---- From rhettinger@users.sourceforge.net Sat Feb 1 02:33:48 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 31 Jan 2003 18:33:48 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_itertools.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv19431 Modified Files: test_itertools.py Log Message: Neaten ref count test. Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_itertools.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_itertools.py 1 Feb 2003 00:10:09 -0000 1.1 --- test_itertools.py 1 Feb 2003 02:33:45 -0000 1.2 *************** *** 152,156 **** for i in xrange(5): test_support.run_suite(suite) ! counts.append(sys.gettotalrefcount()) print counts --- 152,156 ---- for i in xrange(5): test_support.run_suite(suite) ! counts.append(sys.gettotalrefcount()-i) print counts From tim_one@users.sourceforge.net Sat Feb 1 02:54:17 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 18:54:17 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv23548/Lib/test Modified Files: test_datetime.py Log Message: There's no good reason for datetime objects to expose __getstate__() anymore either, so don't. This also allows to get rid of obscure code making __getnewargs__ identical to __getstate__ (hmm ... hope there wasn't more to this than I realize!). Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** test_datetime.py 31 Jan 2003 21:55:33 -0000 1.32 --- test_datetime.py 1 Feb 2003 02:54:14 -0000 1.33 *************** *** 279,284 **** args = 12, 34, 56 orig = timedelta(*args) - state = orig.__getstate__() - self.assertEqual(args, state) for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) --- 279,282 ---- *************** *** 833,838 **** args = 6, 7, 23 orig = self.theclass(*args) - state = orig.__getstate__() - self.assertEqual(state, ('\x00\x06\x07\x17',), self.theclass) for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) --- 831,834 ---- *************** *** 1187,1192 **** args = 6, 7, 23, 20, 59, 1, 64**2 orig = self.theclass(*args) - state = orig.__getstate__() - self.assertEqual(state, ('\x00\x06\x07\x17\x14\x3b\x01\x00\x10\x00',)) for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) --- 1183,1186 ---- *************** *** 1568,1573 **** args = 20, 59, 16, 64**2 orig = self.theclass(*args) - state = orig.__getstate__() - self.assertEqual(state, ('\x14\x3b\x10\x00\x10\x00',)) for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) --- 1562,1565 ---- *************** *** 1878,1883 **** args = 20, 59, 16, 64**2 orig = self.theclass(*args) - state = orig.__getstate__() - self.assertEqual(state, ('\x14\x3b\x10\x00\x10\x00',)) for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) --- 1870,1873 ---- *************** *** 2081,2086 **** args = 6, 7, 23, 20, 59, 1, 64**2 orig = self.theclass(*args) - state = orig.__getstate__() - self.assertEqual(state, ('\x00\x06\x07\x17\x14\x3b\x01\x00\x10\x00',)) for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) --- 2071,2074 ---- From tim_one@users.sourceforge.net Sat Feb 1 02:54:17 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 18:54:17 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.634,1.635 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv23548/Misc Modified Files: NEWS Log Message: There's no good reason for datetime objects to expose __getstate__() anymore either, so don't. This also allows to get rid of obscure code making __getnewargs__ identical to __getstate__ (hmm ... hope there wasn't more to this than I realize!). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.634 retrieving revision 1.635 diff -C2 -d -r1.634 -r1.635 *** NEWS 1 Feb 2003 00:10:09 -0000 1.634 --- NEWS 1 Feb 2003 02:54:15 -0000 1.635 *************** *** 132,137 **** The pickle format of date, time and datetime objects has changed completely. The undocumented pickler and unpickler functions no ! longer exist. The undocumented __setstate__() methods no longer ! exist either. Library --- 132,137 ---- The pickle format of date, time and datetime objects has changed completely. The undocumented pickler and unpickler functions no ! longer exist. The undocumented __setstate__() and __getstate__() ! methods no longer exist either. Library From tim_one@users.sourceforge.net Sat Feb 1 02:54:18 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 18:54:18 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.54,1.55 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv23548/Modules Modified Files: datetimemodule.c Log Message: There's no good reason for datetime objects to expose __getstate__() anymore either, so don't. This also allows to get rid of obscure code making __getnewargs__ identical to __getstate__ (hmm ... hope there wasn't more to this than I realize!). Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.54 retrieving revision 1.55 diff -C2 -d -r1.54 -r1.55 *** datetimemodule.c 1 Feb 2003 02:16:37 -0000 1.54 --- datetimemodule.c 1 Feb 2003 02:54:15 -0000 1.55 *************** *** 1950,1953 **** --- 1950,1954 ---- /* Pickle support, a simple use of __reduce__. */ + /* __getstate__ isn't exposed */ static PyObject * delta_getstate(PyDateTime_Delta *self) *************** *** 1980,1986 **** static PyMethodDef delta_methods[] = { - {"__getstate__", (PyCFunction)delta_getstate, METH_NOARGS, - PyDoc_STR("__getstate__() -> state")}, - {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS, PyDoc_STR("__reduce__() -> (cls, state)")}, --- 1981,1984 ---- *************** *** 2526,2529 **** --- 2524,2528 ---- /* Pickle support, a simple use of __reduce__. */ + /* __getstate__ isn't exposed */ static PyObject * date_getstate(PyDateTime_Date *self) *************** *** 2592,2598 **** PyDoc_STR("Return date with new specified fields.")}, - {"__getstate__", (PyCFunction)date_getstate, METH_NOARGS, - PyDoc_STR("__getstate__() -> state")}, - {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS, PyDoc_STR("__reduce__() -> (cls, state)")}, --- 2591,2594 ---- *************** *** 3341,3344 **** --- 3337,3341 ---- * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo). * So it's a tuple in any (non-error) case. + * __getstate__ isn't exposed. */ static PyObject * *************** *** 3387,3393 **** PyDoc_STR("Return time with new specified fields.")}, - {"__getstate__", (PyCFunction)time_getstate, METH_NOARGS, - PyDoc_STR("__getstate__() -> state")}, - {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS, PyDoc_STR("__reduce__() -> (cls, state)")}, --- 3384,3387 ---- *************** *** 4341,4344 **** --- 4335,4339 ---- * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo). * So it's a tuple in any (non-error) case. + * __getstate__ isn't exposed. */ static PyObject * *************** *** 4432,4438 **** PyDoc_STR("tz -> convert to local time in new timezone tz\n")}, - {"__getstate__", (PyCFunction)datetime_getstate, METH_NOARGS, - PyDoc_STR("__getstate__() -> state")}, - {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS, PyDoc_STR("__reduce__() -> (cls, state)")}, --- 4427,4430 ---- *************** *** 4530,4573 **** if (PyType_Ready(&PyDateTime_TZInfoType) < 0) return; - - /* Make __getnewargs__ a true alias for __getstate__ */ - { - PyObject *d, *f; - - d = PyDateTime_DateType.tp_dict; - f = PyDict_GetItemString(d, "__getstate__"); - if (f != NULL) { - if (PyDict_SetItemString(d, "__getnewargs__", f) < 0) - return; - } - - d = PyDateTime_DateTimeType.tp_dict; - f = PyDict_GetItemString(d, "__getstate__"); - if (f != NULL) { - if (PyDict_SetItemString(d, "__getnewargs__", f) < 0) - return; - } - - d = PyDateTime_DeltaType.tp_dict; - f = PyDict_GetItemString(d, "__getstate__"); - if (f != NULL) { - if (PyDict_SetItemString(d, "__getnewargs__", f) < 0) - return; - } - - d = PyDateTime_TimeType.tp_dict; - f = PyDict_GetItemString(d, "__getstate__"); - if (f != NULL) { - if (PyDict_SetItemString(d, "__getnewargs__", f) < 0) - return; - } - - d = PyDateTime_TZInfoType.tp_dict; - f = PyDict_GetItemString(d, "__getstate__"); - if (f != NULL) { - if (PyDict_SetItemString(d, "__getnewargs__", f) < 0) - return; - } - } /* timedelta values */ --- 4522,4525 ---- From tim_one@users.sourceforge.net Sat Feb 1 03:02:37 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 19:02:37 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.156,1.157 test_datetime.py,1.109,1.110 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv25782 Modified Files: datetime.py test_datetime.py Log Message: __getstate__() isn't needed for pickling anymore, but is used for other things (like hashing and comparison), so make them private methods. This was done earlier for __setstate__() too. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.156 retrieving revision 1.157 diff -C2 -d -r1.156 -r1.157 *** datetime.py 31 Jan 2003 21:52:15 -0000 1.156 --- datetime.py 1 Feb 2003 03:02:33 -0000 1.157 *************** *** 601,608 **** raise TypeError, ("can't compare timedelta to %s instance" % type(other).__name__) ! return cmp(self.__getstate__(), other.__getstate__()) def __hash__(self): ! return hash(self.__getstate__()) def __nonzero__(self): --- 601,608 ---- raise TypeError, ("can't compare timedelta to %s instance" % type(other).__name__) ! return cmp(self.__getstate(), other.__getstate()) def __hash__(self): ! return hash(self.__getstate()) def __nonzero__(self): *************** *** 615,623 **** __safe_for_unpickling__ = True # For Python 2.2 ! def __getstate__(self): return (self.__days, self.__seconds, self.__microseconds) def __reduce__(self): ! return (self.__class__, self.__getstate__()) timedelta.min = timedelta(-999999999) --- 615,623 ---- __safe_for_unpickling__ = True # For Python 2.2 ! def __getstate(self): return (self.__days, self.__seconds, self.__microseconds) def __reduce__(self): ! return (self.__class__, self.__getstate()) timedelta.min = timedelta(-999999999) *************** *** 778,782 **** def __hash__(self): "Hash." ! return hash(self.__getstate__()) # Computations --- 778,782 ---- def __hash__(self): "Hash." ! return hash(self.__getstate()) # Computations *************** *** 853,857 **** __safe_for_unpickling__ = True # For Python 2.2 ! def __getstate__(self): yhi, ylo = divmod(self.__year, 256) return ("%c%c%c%c" % (yhi, ylo, self.__month, self.__day), ) --- 853,857 ---- __safe_for_unpickling__ = True # For Python 2.2 ! def __getstate(self): yhi, ylo = divmod(self.__year, 256) return ("%c%c%c%c" % (yhi, ylo, self.__month, self.__day), ) *************** *** 865,869 **** def __reduce__(self): ! return (self.__class__, self.__getstate__()) _date_class = date # so functions w/ args named "date" can get at the class --- 865,869 ---- def __reduce__(self): ! return (self.__class__, self.__getstate()) _date_class = date # so functions w/ args named "date" can get at the class *************** *** 1038,1042 **** tzoff = self._utcoffset() if not tzoff: # zero or None ! return hash(self.__getstate__()[0]) h, m = divmod(self.hour * 60 + self.minute - tzoff, 60) if 0 <= h < 24: --- 1038,1042 ---- tzoff = self._utcoffset() if not tzoff: # zero or None ! return hash(self.__getstate()[0]) h, m = divmod(self.hour * 60 + self.minute - tzoff, 60) if 0 <= h < 24: *************** *** 1177,1181 **** __safe_for_unpickling__ = True # For Python 2.2 ! def __getstate__(self): us2, us3 = divmod(self.__microsecond, 256) us1, us2 = divmod(us2, 256) --- 1177,1181 ---- __safe_for_unpickling__ = True # For Python 2.2 ! def __getstate(self): us2, us3 = divmod(self.__microsecond, 256) us1, us2 = divmod(us2, 256) *************** *** 1201,1205 **** def __reduce__(self): ! return (self.__class__, self.__getstate__()) _time_class = time # so functions w/ args named "time" can get at the class --- 1201,1205 ---- def __reduce__(self): ! return (self.__class__, self.__getstate()) _time_class = time # so functions w/ args named "time" can get at the class *************** *** 1561,1565 **** tzoff = self._utcoffset() if tzoff is None: ! return hash(self.__getstate__()[0]) days = _ymd2ord(self.year, self.month, self.day) seconds = self.hour * 3600 + (self.minute - tzoff) * 60 + self.second --- 1561,1565 ---- tzoff = self._utcoffset() if tzoff is None: ! return hash(self.__getstate()[0]) days = _ymd2ord(self.year, self.month, self.day) seconds = self.hour * 3600 + (self.minute - tzoff) * 60 + self.second *************** *** 1570,1574 **** __safe_for_unpickling__ = True # For Python 2.2 ! def __getstate__(self): yhi, ylo = divmod(self.__year, 256) us2, us3 = divmod(self.__microsecond, 256) --- 1570,1574 ---- __safe_for_unpickling__ = True # For Python 2.2 ! def __getstate(self): yhi, ylo = divmod(self.__year, 256) us2, us3 = divmod(self.__microsecond, 256) *************** *** 1597,1601 **** def __reduce__(self): ! return (self.__class__, self.__getstate__()) --- 1597,1601 ---- def __reduce__(self): ! return (self.__class__, self.__getstate()) Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.109 retrieving revision 1.110 diff -C2 -d -r1.109 -r1.110 *** test_datetime.py 31 Jan 2003 21:52:15 -0000 1.109 --- test_datetime.py 1 Feb 2003 03:02:34 -0000 1.110 *************** *** 277,282 **** args = 12, 34, 56 orig = timedelta(*args) - state = orig.__getstate__() - self.assertEqual(args, state) for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) --- 277,280 ---- *************** *** 831,836 **** args = 6, 7, 23 orig = self.theclass(*args) - state = orig.__getstate__() - self.assertEqual(state, ('\x00\x06\x07\x17',), self.theclass) for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) --- 829,832 ---- *************** *** 1185,1190 **** args = 6, 7, 23, 20, 59, 1, 64**2 orig = self.theclass(*args) - state = orig.__getstate__() - self.assertEqual(state, ('\x00\x06\x07\x17\x14\x3b\x01\x00\x10\x00',)) for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) --- 1181,1184 ---- *************** *** 1566,1571 **** args = 20, 59, 16, 64**2 orig = self.theclass(*args) - state = orig.__getstate__() - self.assertEqual(state, ('\x14\x3b\x10\x00\x10\x00',)) for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) --- 1560,1563 ---- *************** *** 1876,1881 **** args = 20, 59, 16, 64**2 orig = self.theclass(*args) - state = orig.__getstate__() - self.assertEqual(state, ('\x14\x3b\x10\x00\x10\x00',)) for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) --- 1868,1871 ---- *************** *** 2079,2084 **** args = 6, 7, 23, 20, 59, 1, 64**2 orig = self.theclass(*args) - state = orig.__getstate__() - self.assertEqual(state, ('\x00\x06\x07\x17\x14\x3b\x01\x00\x10\x00',)) for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) --- 2069,2072 ---- From tim_one@users.sourceforge.net Sat Feb 1 04:40:07 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 20:40:07 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.55,1.56 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv16118/Modules Modified Files: datetimemodule.c Log Message: New functions alloc_{time,datetime}. Got rid of all setstate-like functions. Reworked {time,datetime}_new() to do what their corresponding setstates used to do in their state-tuple-input paths, but directly, without constructing an object with throwaway state first. Tightened the "is this a state tuple input?" paths to check the presumed state string-length too, and to raise an exception if the optional second state element isn't a tzinfo instance (IOW, check these paths for type errors as carefully as the normal paths). Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.55 retrieving revision 1.56 diff -C2 -d -r1.55 -r1.56 *** datetimemodule.c 1 Feb 2003 02:54:15 -0000 1.55 --- datetimemodule.c 1 Feb 2003 04:40:04 -0000 1.56 *************** *** 1226,1229 **** --- 1226,1265 ---- /* --------------------------------------------------------------------------- + * Basic object allocation. These allocate Python objects of the right + * size and type, and do the Python object-initialization bit. If there's + * not enough memory, they return NULL after setting MemoryError. All + * data members remain uninitialized trash. + */ + static PyDateTime_Time * + alloc_time(int aware) + { + PyDateTime_Time *self; + + self = (PyDateTime_Time *) + PyObject_MALLOC(aware ? + sizeof(PyDateTime_Time) : + sizeof(_PyDateTime_BaseTime)); + if (self == NULL) + return (PyDateTime_Time *)PyErr_NoMemory(); + PyObject_INIT(self, &PyDateTime_TimeType); + return self; + } + + static PyDateTime_DateTime * + alloc_datetime(int aware) + { + PyDateTime_DateTime *self; + + self = (PyDateTime_DateTime *) + PyObject_MALLOC(aware ? + sizeof(PyDateTime_DateTime) : + sizeof(_PyDateTime_BaseDateTime)); + if (self == NULL) + return (PyDateTime_DateTime *)PyErr_NoMemory(); + PyObject_INIT(self, &PyDateTime_DateTimeType); + return self; + } + + /* --------------------------------------------------------------------------- * Helpers for setting object fields. These work on pointers to the * appropriate base class. *************** *** 1264,1283 **** char aware = tzinfo != Py_None; ! self = (PyDateTime_DateTime *)PyObject_MALLOC(aware ? ! sizeof(PyDateTime_DateTime) : ! sizeof(_PyDateTime_BaseDateTime)); ! if (self == NULL) ! return PyErr_NoMemory(); ! self->hastzinfo = aware; ! set_date_fields((PyDateTime_Date *)self, year, month, day); ! DATE_SET_HOUR(self, hour); ! DATE_SET_MINUTE(self, minute); ! DATE_SET_SECOND(self, second); ! DATE_SET_MICROSECOND(self, usecond); ! if (aware) { ! Py_INCREF(tzinfo); ! self->tzinfo = tzinfo; } ! return (PyObject *)PyObject_INIT(self, &PyDateTime_DateTimeType); } --- 1300,1317 ---- char aware = tzinfo != Py_None; ! self = alloc_datetime(aware); ! if (self != NULL) { ! self->hastzinfo = aware; ! set_date_fields((PyDateTime_Date *)self, year, month, day); ! DATE_SET_HOUR(self, hour); ! DATE_SET_MINUTE(self, minute); ! DATE_SET_SECOND(self, second); ! DATE_SET_MICROSECOND(self, usecond); ! if (aware) { ! Py_INCREF(tzinfo); ! self->tzinfo = tzinfo; ! } } ! return (PyObject *)self; } *************** *** 1289,1308 **** char aware = tzinfo != Py_None; ! self = (PyDateTime_Time *)PyObject_MALLOC(aware ? ! sizeof(PyDateTime_Time) : ! sizeof(_PyDateTime_BaseTime)); ! if (self == NULL) ! return PyErr_NoMemory(); ! self->hastzinfo = aware; ! self->hashcode = -1; ! TIME_SET_HOUR(self, hour); ! TIME_SET_MINUTE(self, minute); ! TIME_SET_SECOND(self, second); ! TIME_SET_MICROSECOND(self, usecond); ! if (aware) { ! Py_INCREF(tzinfo); ! self->tzinfo = tzinfo; } ! return (PyObject *)PyObject_INIT(self, &PyDateTime_TimeType); } --- 1323,1340 ---- char aware = tzinfo != Py_None; ! self = alloc_time(aware); ! if (self != NULL) { ! self->hastzinfo = aware; ! self->hashcode = -1; ! TIME_SET_HOUR(self, hour); ! TIME_SET_MINUTE(self, minute); ! TIME_SET_SECOND(self, second); ! TIME_SET_MICROSECOND(self, usecond); ! if (aware) { ! Py_INCREF(tzinfo); ! self->tzinfo = tzinfo; ! } } ! return (PyObject *)self; } *************** *** 2109,2146 **** static char *date_kws[] = {"year", "month", "day", NULL}; - /* __setstate__ isn't exposed. */ - static PyObject * - date_setstate(PyDateTime_Date *self, PyObject *arg) - { - PyObject *state; - int len; - unsigned char *pdata; - - if (!PyTuple_Check(arg) || PyTuple_GET_SIZE(arg) != 1) - goto error; - state = PyTuple_GET_ITEM(arg, 0); - if (!PyString_Check(state)) - goto error; - - len = PyString_Size(state); - if (len != _PyDateTime_DATE_DATASIZE) - goto error; - - pdata = (unsigned char*)PyString_AsString(state); - memcpy(self->data, pdata, _PyDateTime_DATE_DATASIZE); - self->hashcode = -1; - - Py_INCREF(Py_None); - return Py_None; - error: - PyErr_SetString(PyExc_TypeError, - "bad argument to date.__setstate__"); - return NULL; - } - static PyObject * date_new(PyTypeObject *type, PyObject *args, PyObject *kw) { PyObject *self = NULL; int year; int month; --- 2141,2149 ---- static char *date_kws[] = {"year", "month", "day", NULL}; static PyObject * date_new(PyTypeObject *type, PyObject *args, PyObject *kw) { PyObject *self = NULL; + PyObject *state; int year; int month; *************** *** 2149,2166 **** /* Check for invocation from pickle with __getstate__ state */ if (PyTuple_GET_SIZE(args) == 1 && ! PyString_Check(PyTuple_GET_ITEM(args, 0))) { ! self = new_date(1, 1, 1); ! if (self != NULL) { ! PyObject *res = date_setstate( ! (PyDateTime_Date *)self, args); ! if (res == Py_None) ! Py_DECREF(res); ! else { ! Py_DECREF(self); ! self = NULL; ! } } ! return self; } --- 2152,2167 ---- /* Check for invocation from pickle with __getstate__ state */ if (PyTuple_GET_SIZE(args) == 1 && ! PyString_Check(state = PyTuple_GET_ITEM(args, 0)) && ! PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE) { ! PyDateTime_Date *me; ! ! me = PyObject_New(PyDateTime_Date, &PyDateTime_DateType); ! if (me != NULL) { ! char *pdata = PyString_AS_STRING(state); ! memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE); ! me->hashcode = -1; } ! return (PyObject *)me; } *************** *** 2970,3013 **** "tzinfo", NULL}; - /* __setstate__ isn't exposed. */ - static PyObject * - time_setstate(PyDateTime_Time *self, PyObject *state) - { - PyObject *basestate; - PyObject *tzinfo = Py_None; - - if (! PyArg_ParseTuple(state, "O!|O:__setstate__", - &PyString_Type, &basestate, - &tzinfo)) - return NULL; - if (PyString_Size(basestate) != _PyDateTime_TIME_DATASIZE || - check_tzinfo_subclass(tzinfo) < 0) { - PyErr_SetString(PyExc_TypeError, - "bad argument to time.__setstate__"); - return NULL; - } - if (tzinfo != Py_None && ! HASTZINFO(self)) { - PyErr_SetString(PyExc_ValueError, "time.__setstate__ can't " - "add a non-None tzinfo to a time object that " - "doesn't have one already"); - return NULL; - } - memcpy((char *)self->data, - PyString_AsString(basestate), - _PyDateTime_TIME_DATASIZE); - self->hashcode = -1; - if (HASTZINFO(self)) { - Py_INCREF(tzinfo); - Py_XDECREF(self->tzinfo); - self->tzinfo = tzinfo; - } - Py_INCREF(Py_None); - return Py_None; - } - static PyObject * time_new(PyTypeObject *type, PyObject *args, PyObject *kw) { PyObject *self = NULL; int hour = 0; int minute = 0; --- 2971,2979 ---- "tzinfo", NULL}; static PyObject * time_new(PyTypeObject *type, PyObject *args, PyObject *kw) { PyObject *self = NULL; + PyObject *state; int hour = 0; int minute = 0; *************** *** 3019,3038 **** if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2 && ! PyString_Check(PyTuple_GET_ITEM(args, 0))) { ! if (PyTuple_GET_SIZE(args) == 2) tzinfo = PyTuple_GET_ITEM(args, 1); ! self = new_time(0, 0, 0, 0, tzinfo); ! if (self != NULL) { ! PyObject *res = time_setstate( ! (PyDateTime_Time *)self, args); ! if (res == Py_None) ! Py_DECREF(res); ! else { ! Py_DECREF(self); ! self = NULL; } } ! return self; } --- 2985,3016 ---- if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2 && ! PyString_Check(state = PyTuple_GET_ITEM(args, 0)) && ! PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE) { ! PyDateTime_Time *me; ! char aware; ! ! if (PyTuple_GET_SIZE(args) == 2) { tzinfo = PyTuple_GET_ITEM(args, 1); ! if (check_tzinfo_subclass(tzinfo) < 0) { ! PyErr_SetString(PyExc_TypeError, "bad " ! "tzinfo state arg"); ! return NULL; } } ! aware = (char)(tzinfo != Py_None); ! me = alloc_time(aware); ! if (me != NULL) { ! char *pdata = PyString_AS_STRING(state); ! ! memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE); ! me->hashcode = -1; ! me->hastzinfo = aware; ! if (aware) { ! Py_INCREF(tzinfo); ! me->tzinfo = tzinfo; ! } ! } ! return (PyObject *)me; } *************** *** 3509,3552 **** }; - /* __setstate__ isn't exposed. */ - static PyObject * - datetime_setstate(PyDateTime_DateTime *self, PyObject *state) - { - PyObject *basestate; - PyObject *tzinfo = Py_None; - - if (! PyArg_ParseTuple(state, "O!|O:__setstate__", - &PyString_Type, &basestate, - &tzinfo)) - return NULL; - if (PyString_Size(basestate) != _PyDateTime_DATETIME_DATASIZE || - check_tzinfo_subclass(tzinfo) < 0) { - PyErr_SetString(PyExc_TypeError, - "bad argument to datetime.__setstate__"); - return NULL; - } - if (tzinfo != Py_None && ! HASTZINFO(self)) { - PyErr_SetString(PyExc_ValueError, "datetime.__setstate__ " - "can't add a non-None tzinfo to a datetime " - "object that doesn't have one already"); - return NULL; - } - memcpy((char *)self->data, - PyString_AsString(basestate), - _PyDateTime_DATETIME_DATASIZE); - self->hashcode = -1; - if (HASTZINFO(self)) { - Py_INCREF(tzinfo); - Py_XDECREF(self->tzinfo); - self->tzinfo = tzinfo; - } - Py_INCREF(Py_None); - return Py_None; - } - static PyObject * datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw) { PyObject *self = NULL; int year; int month; --- 3487,3495 ---- }; static PyObject * datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw) { PyObject *self = NULL; + PyObject *state; int year; int month; *************** *** 3561,3580 **** if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2 && ! PyString_Check(PyTuple_GET_ITEM(args, 0))) { ! if (PyTuple_GET_SIZE(args) == 2) tzinfo = PyTuple_GET_ITEM(args, 1); ! self = new_datetime(1, 1, 1, 0, 0, 0, 0, tzinfo); ! if (self != NULL) { ! PyObject *res = datetime_setstate( ! (PyDateTime_DateTime *)self, args); ! if (res == Py_None) ! Py_DECREF(res); ! else { ! Py_DECREF(self); ! self = NULL; } } ! return self; } --- 3504,3535 ---- if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2 && ! PyString_Check(state = PyTuple_GET_ITEM(args, 0)) && ! PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE) { ! PyDateTime_DateTime *me; ! char aware; ! ! if (PyTuple_GET_SIZE(args) == 2) { tzinfo = PyTuple_GET_ITEM(args, 1); ! if (check_tzinfo_subclass(tzinfo) < 0) { ! PyErr_SetString(PyExc_TypeError, "bad " ! "tzinfo state arg"); ! return NULL; } } ! aware = (char)(tzinfo != Py_None); ! me = alloc_datetime(aware); ! if (me != NULL) { ! char *pdata = PyString_AS_STRING(state); ! ! memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE); ! me->hashcode = -1; ! me->hastzinfo = aware; ! if (aware) { ! Py_INCREF(tzinfo); ! me->tzinfo = tzinfo; ! } ! } ! return (PyObject *)me; } From tim_one@users.sourceforge.net Sat Feb 1 06:22:39 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 22:22:39 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.101,2.102 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv7748/Modules Modified Files: cPickle.c Log Message: Added #defines for proto 2 opcodes; gave the Pickler a proto member; removed woefully inadequate opcode docs and pointed to pickletools.py instead. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.101 retrieving revision 2.102 diff -C2 -d -r2.101 -r2.102 *** cPickle.c 1 Feb 2003 02:16:37 -0000 2.101 --- cPickle.c 1 Feb 2003 06:22:36 -0000 2.102 *************** *** 21,39 **** #define WRITE_BUF_SIZE 256 ! /* -------------------------------------------------------------------------- ! NOTES on format codes. ! XXX much more is needed here ! ! Integer types ! BININT1 8-bit unsigned integer; followed by 1 byte. ! BININT2 16-bit unsigned integer; followed by 2 bytes, little-endian. ! BININT 32-bit signed integer; followed by 4 bytes, little-endian. ! INT Integer; natural decimal string conversion, then newline. ! CAUTION: INT-reading code can't assume that what follows ! fits in a Python int, because the size of Python ints varies ! across platforms. ! LONG Long (unbounded) integer; repr(i), then newline. ! -------------------------------------------------------------------------- */ ! #define MARK '(' #define STOP '.' --- 21,28 ---- #define WRITE_BUF_SIZE 256 ! /* ! * Pickle opcodes. These must be kept in synch with pickle.py. Extensive ! * docs are in pickletools.py. ! */ #define MARK '(' #define STOP '.' *************** *** 77,80 **** --- 66,89 ---- #define EMPTY_TUPLE ')' #define SETITEMS 'u' + + /* Protocol 2. */ + #define PROTO '\x80' /* identify pickle protocol */ + #define NEWOBJ '\x81' /* build object by applying cls.__new__ to argtuple */ + #define EXT1 '\x82' /* push object from extension registry; 1-byte index */ + #define EXT2 '\x83' /* ditto, but 2-byte index */ + #define EXT4 '\x84' /* ditto, but 4-byte index */ + #define TUPLE1 '\x85' /* build 1-tuple from stack top */ + #define TUPLE2 '\x86' /* build 2-tuple from two topmost stack items */ + #define TUPLE3 '\x87' /* build 3-tuple from three topmost stack items */ + #define NEWTRUE '\x88' /* push True */ + #define NEWFALSE '\x89' /* push False */ + #define LONG1 '\x8a' /* push long from < 256 bytes */ + #define LONG4 '\x8b' /* push really big long */ + + /* There aren't opcodes -- they're ways to pickle bools before protocol 2, + * so that unpicklers written before bools were introduced unpickle them + * as ints, but unpicklers after can recognize that bools were intended. + * Note that protocol 2 added direct ways to pickle bools. + */ #undef TRUE #define TRUE "I01\n" *************** *** 82,86 **** #define FALSE "I00\n" - static char MARKv = MARK; --- 91,94 ---- *************** *** 270,274 **** --- 278,288 ---- PyObject *pers_func; PyObject *inst_pers_func; + + /* pickle protocol number, >= 0 */ + int proto; + + /* bool, true if proto > 0 */ int bin; + int fast; /* Fast mode doesn't save in memo, don't use if circ ref */ int nesting; From tim_one@users.sourceforge.net Sat Feb 1 06:24:38 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 22:24:38 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.102,2.103 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv8336/Modules Modified Files: cPickle.c Log Message: Trimmed trailing whitespace. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.102 retrieving revision 2.103 diff -C2 -d -r2.102 -r2.103 *** cPickle.c 1 Feb 2003 06:22:36 -0000 2.102 --- cPickle.c 1 Feb 2003 06:24:36 -0000 2.103 *************** *** 119,127 **** static void ! Pdata_dealloc(Pdata *self) { int i; PyObject **p; ! for (i=self->length, p=self->data; --i >= 0; p++) Py_DECREF(*p); --- 119,127 ---- [...2609 lines suppressed...] PickleError) < 0) --- 4745,4749 ---- UnpicklingError, NULL))) return -1; ! if (PyDict_SetItemString(module_dict, "PickleError", PickleError) < 0) *************** *** 4775,4779 **** #endif PyMODINIT_FUNC ! initcPickle(void) { PyObject *m, *d, *di, *v, *k; --- 4775,4779 ---- #endif PyMODINIT_FUNC ! initcPickle(void) { PyObject *m, *d, *di, *v, *k; From tim_one@users.sourceforge.net Sat Feb 1 06:28:01 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 22:28:01 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.103,2.104 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv8925/Modules Modified Files: cPickle.c Log Message: The module docstring had an RCS ID from 1999 embedded in it. Enough already . Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.103 retrieving revision 2.104 diff -C2 -d -r2.103 -r2.104 *** cPickle.c 1 Feb 2003 06:24:36 -0000 2.103 --- cPickle.c 1 Feb 2003 06:27:59 -0000 2.104 *************** *** 4,10 **** PyDoc_STRVAR(cPickle_module_documentation, ! "C implementation and optimization of the Python pickle module\n" ! "\n" ! "cPickle.c,v 1.71 1999/07/11 13:30:34 jim Exp\n"); #ifndef Py_eval_input --- 4,8 ---- PyDoc_STRVAR(cPickle_module_documentation, ! "C implementation and optimization of the Python pickle module."); #ifndef Py_eval_input From tim_one@users.sourceforge.net Sat Feb 1 06:30:14 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 22:30:14 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.104,2.105 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv9429/Modules Modified Files: cPickle.c Log Message: Removed needless include of errno.h. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.104 retrieving revision 2.105 diff -C2 -d -r2.104 -r2.105 *** cPickle.c 1 Feb 2003 06:27:59 -0000 2.104 --- cPickle.c 1 Feb 2003 06:30:12 -0000 2.105 *************** *** 11,18 **** #endif /* Py_eval_input */ - #include - - - #define DEL_LIST_SLICE(list, from, to) (PyList_SetSlice(list, from, to, NULL)) --- 11,14 ---- From jvr@users.sourceforge.net Sat Feb 1 08:34:49 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Sat, 01 Feb 2003 00:34:49 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac bundlebuilder.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv2720/Lib/plat-mac Modified Files: bundlebuilder.py Log Message: icon support by Robin Dunn, closes patch #678218 Index: bundlebuilder.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/bundlebuilder.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** bundlebuilder.py 17 Jan 2003 20:02:06 -0000 1.4 --- bundlebuilder.py 1 Feb 2003 08:34:46 -0000 1.5 *************** *** 282,285 **** --- 282,289 ---- nibname = None + # The name of the icon file to be copied to Resources and used for + # the Finder icon. + iconfile = None + # Symlink the executable instead of copying it. symlink_exec = 0 *************** *** 370,373 **** --- 374,382 ---- os.chmod(bootstrappath, 0775) + if self.iconfile is not None: + iconbase = os.path.basename(self.iconfile) + self.plist.CFBundleIconFile = iconbase + self.files.append((self.iconfile, pathjoin(resdir, iconbase))) + def postProcess(self): if self.standalone: *************** *** 611,614 **** --- 620,625 ---- --nib=NAME main nib name -c, --creator=CCCC 4-char creator code (default: '????') + --iconfile=FILE filename of the icon (an .icns file) to be used + as the Finder icon -l, --link symlink files/folder instead of copying them --link-exec symlink the executable instead of copying it *************** *** 638,642 **** "mainprogram=", "creator=", "nib=", "plist=", "link", "link-exec", "help", "verbose", "quiet", "standalone", ! "exclude=", "include=", "package=", "strip") try: --- 649,653 ---- "mainprogram=", "creator=", "nib=", "plist=", "link", "link-exec", "help", "verbose", "quiet", "standalone", ! "exclude=", "include=", "package=", "strip", "iconfile=") try: *************** *** 658,661 **** --- 669,674 ---- elif opt in ('-c', '--creator'): builder.creator = arg + elif opt == '--iconfile': + builder.iconfile = arg elif opt == "--nib": builder.nibname = arg From jvr@users.sourceforge.net Sat Feb 1 10:07:30 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Sat, 01 Feb 2003 02:07:30 -0800 Subject: [Python-checkins] python/dist/src/Mac/scripts buildpkg.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv25082/Mac/scripts Modified Files: buildpkg.py Log Message: patch #678211 from Robin Dunn Index: buildpkg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/buildpkg.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** buildpkg.py 6 Sep 2002 21:55:13 -0000 1.2 --- buildpkg.py 1 Feb 2003 10:07:28 -0000 1.3 *************** *** 71,74 **** --- 71,75 ---- InstallOnly RequiresReboot + RootVolumeOnly InstallFat\ """ *************** *** 148,151 **** --- 149,153 ---- 'InstallOnly': 'NO', 'RequiresReboot': 'NO', + 'RootVolumeOnly' : 'NO', 'InstallFat': 'NO'} *************** *** 281,291 **** # find pre-process and post-process scripts ! # naming convention: packageName.{pre,post}-{upgrade,install} ! # Alternatively the filenames can be {pre,post}-{upgrade,install} # in which case we prepend the package name packageName = self.packageInfo["Title"] ! for pat in ("*upgrade", "*install"): pattern = join(self.resourceFolder, packageName + pat) allFiles = allFiles + glob.glob(pattern) # check name patterns --- 283,295 ---- # find pre-process and post-process scripts ! # naming convention: packageName.{pre,post}_{upgrade,install} ! # Alternatively the filenames can be {pre,post}_{upgrade,install} # in which case we prepend the package name packageName = self.packageInfo["Title"] ! for pat in ("*upgrade", "*install", "*flight"): pattern = join(self.resourceFolder, packageName + pat) + pattern2 = join(self.resourceFolder, pat) allFiles = allFiles + glob.glob(pattern) + allFiles = allFiles + glob.glob(pattern2) # check name patterns *************** *** 297,309 **** if f[-6:] == ".lproj": files.append((f, f)) ! elif f in ["pre-upgrade", "pre-install", "post-upgrade", "post-install"]: ! files.append((f, self.packageInfo["Title"]+"."+f)) ! elif f[-8:] == "-upgrade": files.append((f,f)) ! elif f[-8:] == "-install": files.append((f,f)) # copy files for src, dst in files: f = join(self.resourceFolder, src) if isfile(f): --- 301,317 ---- if f[-6:] == ".lproj": files.append((f, f)) ! elif basename(f) in ["pre_upgrade", "pre_install", "post_upgrade", "post_install"]: ! files.append((f, packageName+"."+basename(f))) ! elif basename(f) in ["preflight", "postflight"]: ! files.append((f, f)) ! elif f[-8:] == "_upgrade": files.append((f,f)) ! elif f[-8:] == "_install": files.append((f,f)) # copy files for src, dst in files: + src = basename(src) + dst = basename(dst) f = join(self.resourceFolder, src) if isfile(f): From jvr@users.sourceforge.net Sat Feb 1 10:29:48 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Sat, 01 Feb 2003 02:29:48 -0800 Subject: [Python-checkins] python/dist/src/Lib modulefinder.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv30044/Lib Modified Files: modulefinder.py Log Message: removed bizarre construct, no idea why it was there... Index: modulefinder.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/modulefinder.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** modulefinder.py 29 Jan 2003 03:49:43 -0000 1.3 --- modulefinder.py 1 Feb 2003 10:29:45 -0000 1.4 *************** *** 413,417 **** keys.sort() for key in keys: - continue m = self.modules[key] if m.__path__: --- 413,416 ---- From tim_one@users.sourceforge.net Sat Feb 1 16:45:08 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 01 Feb 2003 08:45:08 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.136,1.137 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv16979/Lib Modified Files: pickle.py Log Message: The C pickle now knows how to deal with a proto= argument. Assorted code cleanups, and purged more references to text-vs-binary modes. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.136 retrieving revision 1.137 diff -C2 -d -r1.136 -r1.137 *** pickle.py 31 Jan 2003 19:42:31 -0000 1.136 --- pickle.py 1 Feb 2003 16:45:05 -0000 1.137 *************** *** 175,179 **** protocol is 0, to be backwards compatible. (Protocol 0 is the only protocol that can be written to a file opened in text ! mode and read back successfully.) Protocol 1 is more efficient than protocol 0; protocol 2 is --- 175,181 ---- protocol is 0, to be backwards compatible. (Protocol 0 is the only protocol that can be written to a file opened in text ! mode and read back successfully. When using a protocol higher ! than 0, make sure the file is opened in binary mode, both when ! pickling and unpickling.) Protocol 1 is more efficient than protocol 0; protocol 2 is *************** *** 181,185 **** Specifying a negative protocol version selects the highest ! protocol version supported. The file parameter must have a write() method that accepts a single --- 183,189 ---- Specifying a negative protocol version selects the highest ! protocol version supported. The higher the protocol used, the ! more recent the version of Python needed to read the pickle ! produced. The file parameter must have a write() method that accepts a single *************** *** 210,219 **** def dump(self, obj): ! """Write a pickled representation of obj to the open file. ! ! Either the binary or ASCII format will be used, depending on the ! value of the bin flag passed to the constructor. ! ! """ if self.proto >= 2: self.write(PROTO + chr(self.proto)) --- 214,218 ---- def dump(self, obj): ! """Write a pickled representation of obj to the open file.""" if self.proto >= 2: self.write(PROTO + chr(self.proto)) *************** *** 932,938 **** """This takes a file-like object for reading a pickle data stream. ! This class automatically determines whether the data stream was ! written in binary mode or not, so it does not need a flag as in ! the Pickler class factory. The file-like object must have two methods, a read() method that --- 931,936 ---- """This takes a file-like object for reading a pickle data stream. ! The protocol version of the pickle is detected automatically, so no ! proto argument is needed. The file-like object must have two methods, a read() method that From tim_one@users.sourceforge.net Sat Feb 1 16:45:10 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 01 Feb 2003 08:45:10 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.105,2.106 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv16979/Modules Modified Files: cPickle.c Log Message: The C pickle now knows how to deal with a proto= argument. Assorted code cleanups, and purged more references to text-vs-binary modes. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.105 retrieving revision 2.106 diff -C2 -d -r2.105 -r2.106 *** cPickle.c 1 Feb 2003 06:30:12 -0000 2.105 --- cPickle.c 1 Feb 2003 16:45:06 -0000 2.106 *************** *** 15,18 **** --- 15,21 ---- #define WRITE_BUF_SIZE 256 + /* Bump this when new opcodes are added to the pickle protocol. */ + #define CURRENT_PROTOCOL_NUMBER 2 + /* * Pickle opcodes. These must be kept in synch with pickle.py. Extensive *************** *** 2317,2327 **** static Picklerobject * ! newPicklerobject(PyObject *file, int bin) { Picklerobject *self; ! if (!( self = PyObject_New(Picklerobject, &Picklertype))) return NULL; self->fp = NULL; self->write = NULL; --- 2320,2341 ---- static Picklerobject * ! newPicklerobject(PyObject *file, int proto) { Picklerobject *self; ! if (proto < 0) ! proto = CURRENT_PROTOCOL_NUMBER; ! if (proto > CURRENT_PROTOCOL_NUMBER) { ! PyErr_Format(PyExc_ValueError, "pickle protocol %d asked for; " ! "the highest available protocol is %d", ! proto, CURRENT_PROTOCOL_NUMBER); return NULL; + } + self = PyObject_New(Picklerobject, &Picklertype); + if (self == NULL) + return NULL; + self->proto = proto; + self->bin = proto > 0; self->fp = NULL; self->write = NULL; *************** *** 2331,2335 **** self->inst_pers_func = NULL; self->write_buf = NULL; - self->bin = bin; self->fast = 0; self->nesting = 0; --- 2345,2348 ---- *************** *** 2339,2349 **** self->dispatch_table = NULL; if (file) Py_INCREF(file); ! else ! file=Pdata_New(); ! ! if (!( self->file = file )) ! goto err; if (!( self->memo = PyDict_New())) --- 2352,2364 ---- self->dispatch_table = NULL; + self->file = NULL; if (file) Py_INCREF(file); ! else { ! file = Pdata_New(); ! if (file == NULL) ! goto err; ! } ! self->file = file; if (!( self->memo = PyDict_New())) *************** *** 2353,2357 **** self->fp = PyFile_AsFile(file); if (self->fp == NULL) { ! PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); goto err; } --- 2368,2373 ---- self->fp = PyFile_AsFile(file); if (self->fp == NULL) { ! PyErr_SetString(PyExc_ValueError, ! "I/O operation on closed file"); goto err; } *************** *** 2378,2383 **** } ! if (!( self->write_buf = ! (char *)malloc(WRITE_BUF_SIZE * sizeof(char)))) { PyErr_NoMemory(); goto err; --- 2394,2399 ---- } ! self->write_buf = (char *)PyMem_Malloc(WRITE_BUF_SIZE); ! if (self->write_buf == NULL) { PyErr_NoMemory(); goto err; *************** *** 2402,2406 **** err: ! Py_DECREF((PyObject *)self); return NULL; } --- 2418,2422 ---- err: ! Py_DECREF(self); return NULL; } *************** *** 2411,2423 **** { PyObject *file = NULL; ! int bin = 1; ! if (!PyArg_ParseTuple(args, "|i:Pickler", &bin)) { PyErr_Clear(); ! bin = 0; ! if (!PyArg_ParseTuple(args, "O|i:Pickler", &file, &bin)) return NULL; } ! return (PyObject *)newPicklerobject(file, bin); } --- 2427,2444 ---- { PyObject *file = NULL; ! int proto = 0; ! /* XXX What is this doing? The documented signature is ! * XXX Pickler(file, proto=0), but this accepts Pickler() and ! * XXX Pickler(integer) too. The meaning then is clear as mud. ! * XXX Bug? Feature? ! */ ! if (!PyArg_ParseTuple(args, "|i:Pickler", &proto)) { PyErr_Clear(); ! proto = 0; ! if (!PyArg_ParseTuple(args, "O|i:Pickler", &file, &proto)) return NULL; } ! return (PyObject *)newPicklerobject(file, proto); } *************** *** 2434,2442 **** Py_XDECREF(self->inst_pers_func); Py_XDECREF(self->dispatch_table); ! ! if (self->write_buf) { ! free(self->write_buf); ! } ! PyObject_Del(self); } --- 2455,2459 ---- Py_XDECREF(self->inst_pers_func); Py_XDECREF(self->dispatch_table); ! PyMem_Free(self->write_buf); PyObject_Del(self); } *************** *** 4488,4492 **** --- 4505,4513 ---- } + /* --------------------------------------------------------------------------- + * Module-level functions. + */ + /* dump(obj, file, proto=0). */ static PyObject * cpm_dump(PyObject *self, PyObject *args) *************** *** 4494,4503 **** PyObject *ob, *file, *res = NULL; Picklerobject *pickler = 0; ! int bin = 0; ! if (!( PyArg_ParseTuple(args, "OO|i", &ob, &file, &bin))) goto finally; ! if (!( pickler = newPicklerobject(file, bin))) goto finally; --- 4515,4524 ---- PyObject *ob, *file, *res = NULL; Picklerobject *pickler = 0; ! int proto = 0; ! if (!( PyArg_ParseTuple(args, "OO|i", &ob, &file, &proto))) goto finally; ! if (!( pickler = newPicklerobject(file, proto))) goto finally; *************** *** 4515,4518 **** --- 4536,4540 ---- + /* dumps(obj, proto=0). */ static PyObject * cpm_dumps(PyObject *self, PyObject *args) *************** *** 4520,4526 **** PyObject *ob, *file = 0, *res = NULL; Picklerobject *pickler = 0; ! int bin = 0; ! if (!( PyArg_ParseTuple(args, "O|i:dumps", &ob, &bin))) goto finally; --- 4542,4548 ---- PyObject *ob, *file = 0, *res = NULL; Picklerobject *pickler = 0; ! int proto = 0; ! if (!( PyArg_ParseTuple(args, "O|i:dumps", &ob, &proto))) goto finally; *************** *** 4528,4532 **** goto finally; ! if (!( pickler = newPicklerobject(file, bin))) goto finally; --- 4550,4554 ---- goto finally; ! if (!( pickler = newPicklerobject(file, proto))) goto finally; *************** *** 4544,4547 **** --- 4566,4570 ---- + /* load(fileobj). */ static PyObject * cpm_load(PyObject *self, PyObject *args) *************** *** 4565,4568 **** --- 4588,4592 ---- + /* loads(string) */ static PyObject * cpm_loads(PyObject *self, PyObject *args) *************** *** 4620,4651 **** static struct PyMethodDef cPickle_methods[] = { {"dump", (PyCFunction)cpm_dump, METH_VARARGS, ! PyDoc_STR("dump(object, file, [binary]) --" ! "Write an object in pickle format to the given file\n" "\n" ! "If the optional argument, binary, is provided and is true, then the\n" ! "pickle will be written in binary format, which is more space and\n" ! "computationally efficient. \n") }, {"dumps", (PyCFunction)cpm_dumps, METH_VARARGS, ! PyDoc_STR("dumps(object, [binary]) --" ! "Return a string containing an object in pickle format\n" "\n" ! "If the optional argument, binary, is provided and is true, then the\n" ! "pickle will be written in binary format, which is more space and\n" ! "computationally efficient. \n") }, {"load", (PyCFunction)cpm_load, METH_VARARGS, PyDoc_STR("load(file) -- Load a pickle from the given file")}, {"loads", (PyCFunction)cpm_loads, METH_VARARGS, PyDoc_STR("loads(string) -- Load a pickle from the given string")}, {"Pickler", (PyCFunction)get_Pickler, METH_VARARGS, ! PyDoc_STR("Pickler(file, [binary]) -- Create a pickler\n" "\n" ! "If the optional argument, binary, is provided and is true, then\n" ! "pickles will be written in binary format, which is more space and\n" ! "computationally efficient. \n") }, {"Unpickler", (PyCFunction)get_Unpickler, METH_VARARGS, ! PyDoc_STR("Unpickler(file) -- Create an unpickler")}, { NULL, NULL } }; --- 4644,4694 ---- static struct PyMethodDef cPickle_methods[] = { {"dump", (PyCFunction)cpm_dump, METH_VARARGS, ! PyDoc_STR("dump(object, file, proto=0) -- " ! "Write an object in pickle format to the given file.\n" "\n" ! "See the Pickler docstring for the meaning of optional argument proto.") }, + {"dumps", (PyCFunction)cpm_dumps, METH_VARARGS, ! PyDoc_STR("dumps(object, proto=0) -- " ! "Return a string containing an object in pickle format.\n" "\n" ! "See the Pickler docstring for the meaning of optional argument proto.") }, + {"load", (PyCFunction)cpm_load, METH_VARARGS, PyDoc_STR("load(file) -- Load a pickle from the given file")}, + {"loads", (PyCFunction)cpm_loads, METH_VARARGS, PyDoc_STR("loads(string) -- Load a pickle from the given string")}, + {"Pickler", (PyCFunction)get_Pickler, METH_VARARGS, ! PyDoc_STR("Pickler(file, proto=0) -- Create a pickler.\n" "\n" ! "This takes a file-like object for writing a pickle data stream.\n" ! "The optional proto argument tells the pickler to use the given\n" ! "protocol; supported protocols are 0, 1, 2. The default\n" ! "protocol is 0, to be backwards compatible. (Protocol 0 is the\n" ! "only protocol that can be written to a file opened in text\n" ! "mode and read back successfully. When using a protocol higher\n" ! "than 0, make sure the file is opened in binary mode, both when\n" ! "pickling and unpickling.)\n" ! "\n" ! "Protocol 1 is more efficient than protocol 0; protocol 2 is\n" ! "more efficient than protocol 1.\n" ! "\n" ! "Specifying a negative protocol version selects the highest\n" ! "protocol version supported. The higher the protocol used, the\n" ! "more recent the version of Python needed to read the pickle\n" ! "produced.\n" ! "\n" ! "The file parameter must have a write() method that accepts a single\n" ! "string argument. It can thus be an open file object, a StringIO\n" ! "object, or any other custom object that meets this interface.\n") }, + {"Unpickler", (PyCFunction)get_Unpickler, METH_VARARGS, ! PyDoc_STR("Unpickler(file) -- Create an unpickler.")}, ! { NULL, NULL } }; *************** *** 4684,4689 **** Py_DECREF(copy_reg); - - /* Down to here ********************************** */ if (!( empty_tuple = PyTuple_New(0))) --- 4727,4730 ---- From gvanrossum@users.sourceforge.net Sat Feb 1 19:02:12 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Sat, 01 Feb 2003 11:02:12 -0800 Subject: [Python-checkins] python/nondist/peps pep-0283.txt,1.28,1.29 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv17078 Modified Files: pep-0283.txt Log Message: Remove text about new pickling; refer to PEP 307 instead. Index: pep-0283.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0283.txt,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** pep-0283.txt 7 Jan 2003 02:23:50 -0000 1.28 --- pep-0283.txt 1 Feb 2003 19:02:10 -0000 1.29 *************** *** 27,35 **** guidelines: ! alpha 2 -- late January ! beta 1 -- late February ! beta 2 -- late March ! rc 1 -- late April ! final -- early May --- 27,35 ---- guidelines: ! alpha 2 -- mid February ! beta 1 -- mid March ! beta 2 -- mid April ! rc 1 -- mid May ! final -- end of May *************** *** 39,72 **** - Open issues - - There are some issues that may need more work and/or thought - before the final release (and preferably before the first beta - release). For example: - - - Set API issues; is the sets module perfect? - - I expect it's good enough to stop polishing it until we've had - more widespread user experience. - - - A nicer API to open text files, replacing the ugly (in some - people's eyes) "U" mode flag. There's a proposal out there to - have a new built-in type textfile(filename, mode, encoding). - (Shouldn't it have a bufsize argument too?) - - Ditto. - - - Fredrik Lundh's basetime proposal: - http://effbot.org/ideas/time-type.htm - - I believe this is dead now. - - - New widgets for Tkinter??? - - Has anyone gotten the time for this? *Are* there any new - widgets in Tk 8.4? Note that we've got better Tix support - already (though not on Windows yet). - - Completed features for 2.3 --- 39,42 ---- *************** *** 179,217 **** life of the 2.3 development process. ! - reST is going to be used a lot in Zope3. Maybe it could become ! a standard library module? ! ! - I really, really, really would like to improve pickling of ! new-style classes. ! ! I've finally come to the conclusion that any solution to making ! pickled new-style class instances (and hence pickled datetime ! objects) more efficient will require adding new codes to the ! pickle protocol. ! ! We can do that in Python 2.3. Because this is backwards ! incompatible, I propose that you have to request this protocol ! explicitly. I propose to "upgrade' the binary flag to a general ! "protocol version" flag, with values: ! ! 0 - original protocol ! 1 - binary protocol ! 2 - new protocol ! ! The new protocol can contain an explicit pickle code for the new ! datetime objects. That's about all the thinking I've done so ! far. We need to decide on the new format, but first we must ! figure out ways how to efficiently pickle and unpickle subclass ! instances of (picklable) built-in types, preferably without ! having to copy all the data twice, and instances of new-style ! classes with slots. And we need to implement these twice: in ! Python for pickle.py and in C for cPickle.py. ! ! - I'd also like to get rid of __safe_for_unpickling__ and all ! other pseudo security features. Attempting to unpickle pickles ! from an untrusted source is insane, and nothing can help us ! there; I'd rather make the marshal protocol bulletproof (all it ! needs is a few more checks for inconsistent data and a little ! better error handling). - For a class defined inside another class, the __name__ should be --- 149,153 ---- life of the 2.3 development process. ! - A new pickling protocol. See PEP 307. - For a class defined inside another class, the __name__ should be *************** *** 248,252 **** --- 184,222 ---- + Open issues + + There are some issues that may need more work and/or thought + before the final release (and preferably before the first beta + release). For example: + + - Set API issues; is the sets module perfect? + + I expect it's good enough to stop polishing it until we've had + more widespread user experience. + + - A nicer API to open text files, replacing the ugly (in some + people's eyes) "U" mode flag. There's a proposal out there to + have a new built-in type textfile(filename, mode, encoding). + (Shouldn't it have a bufsize argument too?) + + Ditto. + + - Fredrik Lundh's basetime proposal: + http://effbot.org/ideas/time-type.htm + + I believe this is dead now. + + - New widgets for Tkinter??? + + Has anyone gotten the time for this? *Are* there any new + widgets in Tk 8.4? Note that we've got better Tix support + already (though not on Windows yet). + + Features unlikely to make it into Python 2.3 + + - reST is going to be used a lot in Zope3. Maybe it could become + a standard library module? (Since reST's author thinks it's too + instable, I'm inclined not to do this.) - Decide on a clearer deprecation policy (especially for modules) From gvanrossum@users.sourceforge.net Sat Feb 1 20:10:38 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Sat, 01 Feb 2003 12:10:38 -0800 Subject: [Python-checkins] python/nondist/peps pep-0307.txt,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv5868 Modified Files: pep-0307.txt Log Message: Add __newobj__ and TBD section. Index: pep-0307.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0307.txt,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** pep-0307.txt 31 Jan 2003 21:58:34 -0000 1.4 --- pep-0307.txt 1 Feb 2003 20:10:35 -0000 1.5 *************** *** 134,141 **** function A callable object (not necessarily a function) called ! to create the initial version of the object; state may ! be added to the object later to fully reconstruct the ! pickled state. This function must itself be ! picklable. arguments A tuple giving the argument list for the function. --- 134,142 ---- function A callable object (not necessarily a function) called ! to create the initial version of the object; state ! may be added to the object later to fully reconstruct ! the pickled state. This function must itself be ! picklable. See the section about __newobj__ for a ! special case (new in this PEP) here. arguments A tuple giving the argument list for the function. *************** *** 183,186 **** --- 184,213 ---- 2.3, __setstate__ will never be called when __reduce__ returns a state with value None. + + + The __newobj__ unpickling function + + When the unpickling function returned by __reduce__ (the first + item of the returned tuple) has the name __newobj__, something + special happens for pickle protocol 2. An unpickling function + named __newobj__ is assumed to have the following semantics: + + def __newobj__(cls, *args): + return cls.__new__(cls, *args) + + Pickle protocol 2 special-cases an unpickling function with this + name, and emits a pickling opcode that, given 'cls' and 'args', + will return cls.__new__(cls, *args) without also pickling a + reference to __newobj__. This is the main reason why protocol 2 + pickles are so much smaller than classic pickles. Of course, the + pickling code cannot verify that a function named __newobj__ + actually has the expected semantics. If you use an unpickling + function named __newobj__ that returns something different, you + deserve what you get. + + + TBD + + The rest of this PEP is still under construction! From neal@metaslash.com Sat Feb 1 23:01:32 2003 From: neal@metaslash.com (Neal Norwitz) Date: Sat, 01 Feb 2003 18:01:32 -0500 Subject: [Python-checkins] python/dist/src/Objects longobject.c,1.148,1.149 In-Reply-To: References: Message-ID: <20030201230132.GI24222@epoch.metaslash.com> > + _PyLong_Sign(PyObject *vv) > + { > + PyLongObject *v = (PyLongObject *)vv; > + const int ndigits = v->ob_size; > + > + assert(v != NULL); Not sure how useful this assert is since v was already dereferenced on the line above (v->ob_size). Neal From tim_one@email.msn.com Sat Feb 1 23:58:20 2003 From: tim_one@email.msn.com (Tim Peters) Date: Sat, 1 Feb 2003 18:58:20 -0500 Subject: [Python-checkins] python/dist/src/Objects longobject.c,1.148,1.149 In-Reply-To: <20030201230132.GI24222@epoch.metaslash.com> Message-ID: >> + _PyLong_Sign(PyObject *vv) >> + { >> + PyLongObject *v = (PyLongObject *)vv; >> + const int ndigits = v->ob_size; >> + >> + assert(v != NULL); [Neal Norwitz] > Not sure how useful this assert is since v was already > dereferenced on the line above (v->ob_size). Its only use is to the human reader, who, when this blows up, looks at the code. Then the assert() clearly communicates that v != NULL is a precondition for calling this internal API function. If the assert() weren't there, the reader would have to guess (or read the comment before the declaration in the .h file -- but that's too much to ask ). From tim_one@users.sourceforge.net Sun Feb 2 02:57:54 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 01 Feb 2003 18:57:54 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.137,1.138 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv8448/Lib Modified Files: pickle.py Log Message: cPickle.c: Full support for the new LONG1 and LONG4. Added comments. Assorted code cleanups; e.g., sizeof(char) is 1 by definition, so there's no need to do things like multiply by sizeof(char) in hairy malloc arguments. Fixed an undetected-overflow bug in readline_file(). longobject.c: Fixed a really stupid bug in the new _PyLong_NumBits. pickle.py: Fixed stupid bug in save_long(): When proto is 2, it wrote LONG1 or LONG4, but forgot to return then -- it went on to append the proto 1 LONG opcode too. Fixed equally stupid cancelling bugs in load_long1() and load_long4(): they *returned* the unpickled long instead of pushing it on the stack. The return values were ignored. Tests passed before only because save_long() pickled the long twice. Fixed bugs in encode_long(). Noted that decode_long() is quadratic-time despite our hopes, because long(string, 16) is still quadratic-time in len(string). It's hex() that's linear-time. I don't know a way to make decode_long() linear-time in Python, short of maybe transforming the 256's-complement bytes into marshal's funky internal format, and letting marshal decode that. It would be more valuable to make long(string, 16) linear time. pickletester.py: Added a global "protocols" vector so tests can try all the protocols in a sane way. Changed test_ints() and test_unicode() to do so. Added a new test_long(), but the tail end of it is disabled because it "takes forever" under pickle.py (but runs very quickly under cPickle: cPickle proto 2 for longs is linear-time). Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.137 retrieving revision 1.138 diff -C2 -d -r1.137 -r1.138 *** pickle.py 1 Feb 2003 16:45:05 -0000 1.137 --- pickle.py 2 Feb 2003 02:57:52 -0000 1.138 *************** *** 554,557 **** --- 554,558 ---- else: self.write(LONG4 + pack(" 0 ashex = hex(x) ! if x >> (nbits - 1) == 0: # "looks positive", so need a byte of sign bits ! ashex = "0xff" + x[2:] if ashex.endswith('L'): --- 1412,1422 ---- assert x > 0 ashex = hex(x) ! njunkchars = 2 + ashex.endswith('L') ! newnibbles = len(ashex) - njunkchars ! if newnibbles < nibbles: ! ashex = "0x" + "0" * (nibbles - newnibbles) + ashex[2:] ! if int(ashex[2], 16) < 8: # "looks positive", so need a byte of sign bits ! ashex = "0xff" + ashex[2:] if ashex.endswith('L'): *************** *** 1419,1426 **** else: ashex = ashex[2:] ! assert len(ashex) & 1 == 0 binary = _binascii.unhexlify(ashex) return binary[::-1] def decode_long(data): r"""Decode a long from a two's complement little-endian binary string. --- 1424,1434 ---- else: ashex = ashex[2:] ! assert len(ashex) & 1 == 0, (x, ashex) binary = _binascii.unhexlify(ashex) return binary[::-1] + # XXX OOPS! This is still quadratic-time. While hex(n) is linear-time + # XXX in the # of digits in n, long(s, 16) is still quadratic-time + # XXX in len(s). def decode_long(data): r"""Decode a long from a two's complement little-endian binary string. *************** *** 1446,1450 **** return 0L ashex = _binascii.hexlify(data[::-1]) ! n = long(ashex, 16) if data[-1] >= '\x80': n -= 1L << (nbytes * 8) --- 1454,1458 ---- return 0L ashex = _binascii.hexlify(data[::-1]) ! n = long(ashex, 16) # quadratic time if data[-1] >= '\x80': n -= 1L << (nbytes * 8) From tim_one@users.sourceforge.net Sun Feb 2 02:57:54 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 01 Feb 2003 18:57:54 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv8448/Lib/test Modified Files: pickletester.py Log Message: cPickle.c: Full support for the new LONG1 and LONG4. Added comments. Assorted code cleanups; e.g., sizeof(char) is 1 by definition, so there's no need to do things like multiply by sizeof(char) in hairy malloc arguments. Fixed an undetected-overflow bug in readline_file(). longobject.c: Fixed a really stupid bug in the new _PyLong_NumBits. pickle.py: Fixed stupid bug in save_long(): When proto is 2, it wrote LONG1 or LONG4, but forgot to return then -- it went on to append the proto 1 LONG opcode too. Fixed equally stupid cancelling bugs in load_long1() and load_long4(): they *returned* the unpickled long instead of pushing it on the stack. The return values were ignored. Tests passed before only because save_long() pickled the long twice. Fixed bugs in encode_long(). Noted that decode_long() is quadratic-time despite our hopes, because long(string, 16) is still quadratic-time in len(string). It's hex() that's linear-time. I don't know a way to make decode_long() linear-time in Python, short of maybe transforming the 256's-complement bytes into marshal's funky internal format, and letting marshal decode that. It would be more valuable to make long(string, 16) linear time. pickletester.py: Added a global "protocols" vector so tests can try all the protocols in a sane way. Changed test_ints() and test_unicode() to do so. Added a new test_long(), but the tail end of it is disabled because it "takes forever" under pickle.py (but runs very quickly under cPickle: cPickle proto 2 for longs is linear-time). Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** pickletester.py 1 Feb 2003 02:16:36 -0000 1.31 --- pickletester.py 2 Feb 2003 02:57:52 -0000 1.32 *************** *** 2,5 **** --- 2,10 ---- from test.test_support import TestFailed, have_unicode, TESTFN + # Tests that try a number of pickle protocols should have a + # for proto in protocols: + # kind of outer loop. Bump the 3 to 4 if/when protocol 3 is invented. + protocols = range(3) + class C: def __cmp__(self, other): *************** *** 29,32 **** --- 34,40 ---- __metaclass__ = metaclass + # DATA and BINDATA are the protocol 0 and protocol 1 pickles of the object + # returned by create_data(). + # break into multiple strings to avoid confusing font-lock-mode DATA = """(lp1 *************** *** 211,228 **** endcases = [unicode(''), unicode('<\\u>'), unicode('<\\\u1234>'), unicode('<\n>'), unicode('<\\>')] ! for u in endcases: ! p = self.dumps(u) ! u2 = self.loads(p) ! self.assertEqual(u2, u) def test_ints(self): import sys ! n = sys.maxint ! while n: ! for expected in (-n, n): ! s = self.dumps(expected) ! n2 = self.loads(s) ! self.assertEqual(expected, n2) ! n = n >> 1 def test_maxint64(self): --- 219,238 ---- endcases = [unicode(''), unicode('<\\u>'), unicode('<\\\u1234>'), unicode('<\n>'), unicode('<\\>')] ! for proto in protocols: ! for u in endcases: ! p = self.dumps(u, proto) ! u2 = self.loads(p) ! self.assertEqual(u2, u) def test_ints(self): import sys ! for proto in protocols: ! n = sys.maxint ! while n: ! for expected in (-n, n): ! s = self.dumps(expected, proto) ! n2 = self.loads(s) ! self.assertEqual(expected, n2) ! n = n >> 1 def test_maxint64(self): *************** *** 235,238 **** --- 245,276 ---- data = 'I' + str(maxint64) + 'JUNK\n.' self.assertRaises(ValueError, self.loads, data) + + def test_long(self): + for proto in protocols: + # 256 bytes is where LONG4 begins + for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257: + nbase = 1L << nbits + for npos in nbase-1, nbase, nbase+1: + for n in npos, -npos: + pickle = self.dumps(n, proto) + got = self.loads(pickle) + self.assertEqual(n, got) + # Try a monster. This is quadratic-time in protos 0 & 1, so don't + # bother with those. + # XXX Damn. pickle.py is still quadratic-time here, due to + # XXX long(string, 16). cPickle runs this in an eyeblink, but I + # XXX gave up waiting for pickle.py to get beyond "loading". Giving + # XXX up for now. + return + print "building long" + nbase = long("deadbeeffeedface", 16) + nbase += nbase << 1000000 + for n in nbase, -nbase: + print "dumping" + p = self.dumps(n, 2) + print "loading" + got = self.loads(p) + print "checking" + self.assertEqual(n, got) def test_reduce(self): From tim_one@users.sourceforge.net Sun Feb 2 02:57:55 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 01 Feb 2003 18:57:55 -0800 Subject: [Python-checkins] python/dist/src/Objects longobject.c,1.150,1.151 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv8448/Objects Modified Files: longobject.c Log Message: cPickle.c: Full support for the new LONG1 and LONG4. Added comments. Assorted code cleanups; e.g., sizeof(char) is 1 by definition, so there's no need to do things like multiply by sizeof(char) in hairy malloc arguments. Fixed an undetected-overflow bug in readline_file(). longobject.c: Fixed a really stupid bug in the new _PyLong_NumBits. pickle.py: Fixed stupid bug in save_long(): When proto is 2, it wrote LONG1 or LONG4, but forgot to return then -- it went on to append the proto 1 LONG opcode too. Fixed equally stupid cancelling bugs in load_long1() and load_long4(): they *returned* the unpickled long instead of pushing it on the stack. The return values were ignored. Tests passed before only because save_long() pickled the long twice. Fixed bugs in encode_long(). Noted that decode_long() is quadratic-time despite our hopes, because long(string, 16) is still quadratic-time in len(string). It's hex() that's linear-time. I don't know a way to make decode_long() linear-time in Python, short of maybe transforming the 256's-complement bytes into marshal's funky internal format, and letting marshal decode that. It would be more valuable to make long(string, 16) linear time. pickletester.py: Added a global "protocols" vector so tests can try all the protocols in a sane way. Changed test_ints() and test_unicode() to do so. Added a new test_long(), but the tail end of it is disabled because it "takes forever" under pickle.py (but runs very quickly under cPickle: cPickle proto 2 for longs is linear-time). Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.150 retrieving revision 1.151 diff -C2 -d -r1.150 -r1.151 *** longobject.c 31 Jan 2003 21:45:13 -0000 1.150 --- longobject.c 2 Feb 2003 02:57:53 -0000 1.151 *************** *** 265,269 **** { PyLongObject *v = (PyLongObject *)vv; ! const int ndigits = v->ob_size; assert(v != NULL); --- 265,269 ---- { PyLongObject *v = (PyLongObject *)vv; ! const int ndigits = ABS(v->ob_size); assert(v != NULL); *************** *** 271,275 **** assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); ! return ndigits == 0 ? 0 : (ndigits < 0 ? -1 : 1); } --- 271,275 ---- assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); ! return v->ob_size == 0 ? 0 : (v->ob_size < 0 ? -1 : 1); } From tim_one@users.sourceforge.net Sun Feb 2 02:57:55 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 01 Feb 2003 18:57:55 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.106,2.107 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv8448/Modules Modified Files: cPickle.c Log Message: cPickle.c: Full support for the new LONG1 and LONG4. Added comments. Assorted code cleanups; e.g., sizeof(char) is 1 by definition, so there's no need to do things like multiply by sizeof(char) in hairy malloc arguments. Fixed an undetected-overflow bug in readline_file(). longobject.c: Fixed a really stupid bug in the new _PyLong_NumBits. pickle.py: Fixed stupid bug in save_long(): When proto is 2, it wrote LONG1 or LONG4, but forgot to return then -- it went on to append the proto 1 LONG opcode too. Fixed equally stupid cancelling bugs in load_long1() and load_long4(): they *returned* the unpickled long instead of pushing it on the stack. The return values were ignored. Tests passed before only because save_long() pickled the long twice. Fixed bugs in encode_long(). Noted that decode_long() is quadratic-time despite our hopes, because long(string, 16) is still quadratic-time in len(string). It's hex() that's linear-time. I don't know a way to make decode_long() linear-time in Python, short of maybe transforming the 256's-complement bytes into marshal's funky internal format, and letting marshal decode that. It would be more valuable to make long(string, 16) linear time. pickletester.py: Added a global "protocols" vector so tests can try all the protocols in a sane way. Changed test_ints() and test_unicode() to do so. Added a new test_long(), but the tail end of it is disabled because it "takes forever" under pickle.py (but runs very quickly under cPickle: cPickle proto 2 for longs is linear-time). Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.106 retrieving revision 2.107 diff -C2 -d -r2.106 -r2.107 *** cPickle.c 1 Feb 2003 16:45:06 -0000 2.106 --- cPickle.c 2 Feb 2003 02:57:52 -0000 2.107 *************** *** 465,469 **** static int ! read_file(Unpicklerobject *self, char **s, int n) { size_t nbytesread; --- 465,469 ---- static int ! read_file(Unpicklerobject *self, char **s, int n) { size_t nbytesread; *************** *** 473,477 **** size = ((n < 32) ? 32 : n); ! if (!( self->buf = (char *)malloc(size * sizeof(char)))) { PyErr_NoMemory(); return -1; --- 473,477 ---- size = ((n < 32) ? 32 : n); ! if (!( self->buf = (char *)malloc(size))) { PyErr_NoMemory(); return -1; *************** *** 481,490 **** } else if (n > self->buf_size) { ! self->buf = (char *)realloc(self->buf, n * sizeof(char)); if (!self->buf) { PyErr_NoMemory(); return -1; } - self->buf_size = n; } --- 481,489 ---- } else if (n > self->buf_size) { ! self->buf = (char *)realloc(self->buf, n); if (!self->buf) { PyErr_NoMemory(); return -1; } self->buf_size = n; } *************** *** 515,523 **** if (self->buf_size == 0) { ! if (!( self->buf = (char *)malloc(40 * sizeof(char)))) { PyErr_NoMemory(); return -1; } - self->buf_size = 40; } --- 514,521 ---- if (self->buf_size == 0) { ! if (!( self->buf = (char *)malloc(40))) { PyErr_NoMemory(); return -1; } self->buf_size = 40; } *************** *** 525,528 **** --- 523,527 ---- i = 0; while (1) { + int bigger; for (; i < (self->buf_size - 1); i++) { if (feof(self->fp) || *************** *** 533,544 **** } } ! self->buf = (char *)realloc(self->buf, ! (self->buf_size * 2) * sizeof(char)); if (!self->buf) { PyErr_NoMemory(); return -1; } ! ! self->buf_size *= 2; } } --- 532,546 ---- } } ! bigger = self->buf_size << 1; ! if (bigger <= 0) { /* overflow */ ! PyErr_NoMemory(); ! return -1; ! } ! self->buf = (char *)realloc(self->buf, bigger); if (!self->buf) { PyErr_NoMemory(); return -1; } ! self->buf_size = bigger; } } *************** *** 621,632 **** } ! static char * ! pystrndup(char *s, int l) { ! char *r; ! if (!( r=malloc((l+1)*sizeof(char)))) return (char*)PyErr_NoMemory(); ! memcpy(r,s,l); ! r[l]=0; return r; } --- 623,638 ---- } ! /* Copy the first n bytes from s into newly malloc'ed memory, plus a ! * trailing 0 byte. Return a pointer to that, or NULL if out of memory. ! * The caller is responsible for free()'ing the return value. ! */ static char * ! pystrndup(char *s, int n) { ! char *r = (char *)malloc(n+1); ! if (r == NULL) ! return (char*)PyErr_NoMemory(); ! memcpy(r, s, n); ! r[n] = 0; return r; } *************** *** 1013,1021 **** save_long(Picklerobject *self, PyObject *args) { ! int size, res = -1; ! PyObject *repr = 0; static char l = LONG; if (!( repr = PyObject_Repr(args))) goto finally; --- 1019,1109 ---- save_long(Picklerobject *self, PyObject *args) { ! int size; ! int res = -1; ! PyObject *repr = NULL; static char l = LONG; + if (self->proto >= 2) { + /* Linear-time pickling. */ + size_t nbits; + size_t nbytes; + unsigned char *pdata; + char c_str[5]; + int i; + int sign = _PyLong_Sign(args); + + if (sign == 0) { + /* It's 0 -- an empty bytestring. */ + c_str[0] = LONG1; + c_str[1] = 0; + i = self->write_func(self, c_str, 2); + if (i < 0) goto finally; + res = 0; + goto finally; + } + nbits = _PyLong_NumBits(args); + if (nbits == (size_t)-1 && PyErr_Occurred()) + goto finally; + /* How many bytes do we need? There are nbits >> 3 full + * bytes of data, and nbits & 7 leftover bits. If there + * are any leftover bits, then we clearly need another + * byte. Wnat's not so obvious is that we *probably* + * need another byte even if there aren't any leftovers: + * the most-significant bit of the most-significant byte + * acts like a sign bit, and it's usually got a sense + * opposite of the one we need. The exception is longs + * of the form -(2**(8*j-1)) for j > 0. Such a long is + * its own 256's-complement, so has the right sign bit + * even without the extra byte. That's a pain to check + * for in advance, though, so we always grab an extra + * byte at the start, and cut it back later if possible. + */ + nbytes = (nbits >> 3) + 1; + if ((int)nbytes < 0 || (size_t)(int)nbytes != nbytes) { + PyErr_SetString(PyExc_OverflowError, "long too large " + "to pickle"); + goto finally; + } + repr = PyString_FromStringAndSize(NULL, (int)nbytes); + if (repr == NULL) goto finally; + pdata = (unsigned char *)PyString_AS_STRING(repr); + i = _PyLong_AsByteArray((PyLongObject *)args, + pdata, nbytes, + 1 /* little endian */, 1 /* signed */); + if (i < 0) goto finally; + /* If the long is negative, this may be a byte more than + * needed. This is so iff the MSB is all redundant sign + * bits. + */ + if (sign < 0 && nbytes > 1 && pdata[nbytes - 1] == 0xff && + (pdata[nbytes - 2] & 0x80) != 0) + --nbytes; + + if (nbytes < 256) { + c_str[0] = LONG1; + c_str[1] = (char)nbytes; + size = 2; + } + else { + c_str[0] = LONG4; + size = (int)nbytes; + for (i = 1; i < 5; i++) { + c_str[i] = (char)(size & 0xff); + size >>= 8; + } + size = 5; + } + i = self->write_func(self, c_str, size); + if (i < 0) goto finally; + i = self->write_func(self, (char *)pdata, (int)nbytes); + if (i < 0) goto finally; + res = 0; + goto finally; + } + + /* proto < 2: write the repr and newline. This is quadratic-time + * (in the number of digits), in both directions. + */ if (!( repr = PyObject_Repr(args))) goto finally; *************** *** 1039,1043 **** finally: Py_XDECREF(repr); - return res; } --- 1127,1130 ---- *************** *** 2688,2694 **** } ! static long ! calc_binint(char *s, int x) { unsigned char c; --- 2775,2785 ---- } ! /* s contains x bytes of a little-endian integer. Return its value as a ! * C int. Obscure: when x is 1 or 2, this is an unsigned little-endian ! * int, but when x is 4 it's a signed one. This is an historical source ! * of x-platform bugs. ! */ static long ! calc_binint(char *s, int x) { unsigned char c; *************** *** 2787,2790 **** --- 2878,2920 ---- } + /* 'size' bytes contain the # of bytes of little-endian 256's-complement + * data following. + */ + static int + load_counted_long(Unpicklerobject *self, int size) + { + int i; + char *nbytes; + unsigned char *pdata; + PyObject *along; + + assert(size == 1 || size == 4); + i = self->read_func(self, &nbytes, size); + if (i < 0) return -1; + + size = calc_binint(nbytes, size); + if (size < 0) { + /* Corrupt or hostile pickle -- we never write one like + * this. + */ + PyErr_SetString(PyExc_ValueError, "LONG pickle has negative " + "byte count"); + return -1; + } + + if (size == 0) + along = PyLong_FromLong(0L); + else { + /* Read the raw little-endian bytes & convert. */ + i = self->read_func(self, &(char *)pdata, size); + if (i < 0) return -1; + along = _PyLong_FromByteArray(pdata, (size_t)size, + 1 /* little endian */, 1 /* signed */); + } + if (along == NULL) + return -1; + PDATA_PUSH(self->stack, along, -1); + return 0; + } static int *************** *** 3782,3785 **** --- 3912,3925 ---- case LONG: if (load_long(self) < 0) + break; + continue; + + case LONG1: + if (load_counted_long(self, 1) < 0) + break; + continue; + + case LONG4: + if (load_counted_long(self, 4) < 0) break; continue; From fdrake@users.sourceforge.net Sun Feb 2 03:54:19 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Sat, 01 Feb 2003 19:54:19 -0800 Subject: [Python-checkins] python/dist/src/Modules pyexpat.c,2.79,2.80 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv22705/Modules Modified Files: pyexpat.c Log Message: Fix memory leak: free memory storing the content model passed to the ElementDeclHandler by Expat. Fixes SF bug #676990. Index: pyexpat.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/pyexpat.c,v retrieving revision 2.79 retrieving revision 2.80 diff -C2 -d -r2.79 -r2.80 *** pyexpat.c 21 Jan 2003 11:09:21 -0000 2.79 --- pyexpat.c 2 Feb 2003 03:54:17 -0000 2.80 *************** *** 684,716 **** } ! static PyObject * ! conv_content_model_utf8(XML_Content * const model) { ! return conv_content_model(model, conv_string_to_utf8); ! } ! #ifdef Py_USING_UNICODE ! static PyObject * ! conv_content_model_unicode(XML_Content * const model) ! { ! return conv_content_model(model, conv_string_to_unicode); ! } ! VOID_HANDLER(ElementDecl, ! (void *userData, ! const XML_Char *name, ! XML_Content *model), ! ("NO&", ! string_intern(self, name), ! (self->returns_unicode ? conv_content_model_unicode ! : conv_content_model_utf8),model)) #else ! VOID_HANDLER(ElementDecl, ! (void *userData, ! const XML_Char *name, ! XML_Content *model), ! ("NO&", ! string_intern(self, name), conv_content_model_utf8,model)) #endif VOID_HANDLER(AttlistDecl, --- 684,740 ---- } ! static void ! my_ElementDeclHandler(void *userData, ! const XML_Char *name, ! XML_Content *model) { ! xmlparseobject *self = (xmlparseobject *)userData; ! PyObject *args = NULL; ! if (have_handler(self, ElementDecl)) { ! PyObject *rv = NULL; ! PyObject *modelobj, *nameobj; ! if (flush_character_buffer(self) < 0) ! goto finally; ! #ifdef Py_USING_UNICODE ! modelobj = conv_content_model(model, ! (self->returns_unicode ! ? conv_string_to_unicode ! : conv_string_to_utf8)); #else ! modelobj = conv_content_model(model, conv_string_to_utf8); #endif + if (modelobj == NULL) { + flag_error(self); + goto finally; + } + nameobj = string_intern(self, name); + if (nameobj == NULL) { + Py_DECREF(modelobj); + flag_error(self); + goto finally; + } + args = Py_BuildValue("NN", string_intern(self, name), modelobj); + if (args == NULL) { + Py_DECREF(modelobj); + flag_error(self); + goto finally; + } + self->in_callback = 1; + rv = call_with_frame(getcode(ElementDecl, "ElementDecl", __LINE__), + self->handlers[ElementDecl], args); + self->in_callback = 0; + if (rv == NULL) { + flag_error(self); + goto finally; + } + Py_DECREF(rv); + } + finally: + Py_XDECREF(args); + XML_FreeContentModel(self->itself, model); + return; + } VOID_HANDLER(AttlistDecl, From tim_one@users.sourceforge.net Sun Feb 2 07:51:34 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 01 Feb 2003 23:51:34 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv7771/Lib/test Modified Files: pickletester.py Log Message: long(string, base) now takes time linear in len(string) when base is a power of 2. Enabled the tail end of test_long() in pickletester.py because it no longer takes forever when run from test_pickle.py. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** pickletester.py 2 Feb 2003 02:57:52 -0000 1.32 --- pickletester.py 2 Feb 2003 07:51:32 -0000 1.33 *************** *** 248,252 **** def test_long(self): for proto in protocols: ! # 256 bytes is where LONG4 begins for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257: nbase = 1L << nbits --- 248,252 ---- def test_long(self): for proto in protocols: ! # 256 bytes is where LONG4 begins. for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257: nbase = 1L << nbits *************** *** 258,275 **** # Try a monster. This is quadratic-time in protos 0 & 1, so don't # bother with those. - # XXX Damn. pickle.py is still quadratic-time here, due to - # XXX long(string, 16). cPickle runs this in an eyeblink, but I - # XXX gave up waiting for pickle.py to get beyond "loading". Giving - # XXX up for now. - return - print "building long" nbase = long("deadbeeffeedface", 16) nbase += nbase << 1000000 for n in nbase, -nbase: - print "dumping" p = self.dumps(n, 2) - print "loading" got = self.loads(p) - print "checking" self.assertEqual(n, got) --- 258,266 ---- From tim_one@users.sourceforge.net Sun Feb 2 07:51:34 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 01 Feb 2003 23:51:34 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.138,1.139 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv7771/Lib Modified Files: pickle.py Log Message: long(string, base) now takes time linear in len(string) when base is a power of 2. Enabled the tail end of test_long() in pickletester.py because it no longer takes forever when run from test_pickle.py. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.138 retrieving revision 1.139 diff -C2 -d -r1.138 -r1.139 *** pickle.py 2 Feb 2003 02:57:52 -0000 1.138 --- pickle.py 2 Feb 2003 07:51:32 -0000 1.139 *************** *** 1428,1434 **** return binary[::-1] - # XXX OOPS! This is still quadratic-time. While hex(n) is linear-time - # XXX in the # of digits in n, long(s, 16) is still quadratic-time - # XXX in len(s). def decode_long(data): r"""Decode a long from a two's complement little-endian binary string. --- 1428,1431 ---- *************** *** 1454,1458 **** return 0L ashex = _binascii.hexlify(data[::-1]) ! n = long(ashex, 16) # quadratic time if data[-1] >= '\x80': n -= 1L << (nbytes * 8) --- 1451,1455 ---- return 0L ashex = _binascii.hexlify(data[::-1]) ! n = long(ashex, 16) # quadratic time before Python 2.3; linear now if data[-1] >= '\x80': n -= 1L << (nbytes * 8) From tim_one@users.sourceforge.net Sun Feb 2 07:51:34 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 01 Feb 2003 23:51:34 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.635,1.636 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv7771/Misc Modified Files: NEWS Log Message: long(string, base) now takes time linear in len(string) when base is a power of 2. Enabled the tail end of test_long() in pickletester.py because it no longer takes forever when run from test_pickle.py. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.635 retrieving revision 1.636 diff -C2 -d -r1.635 -r1.636 *** NEWS 1 Feb 2003 02:54:15 -0000 1.635 --- NEWS 2 Feb 2003 07:51:32 -0000 1.636 *************** *** 13,16 **** --- 13,19 ---- ----------------- + - long(string, base) takes time linear in len(string) when base is a power + of 2 now. It used to take time quadratic in len(string). + - filter returns now Unicode results for Unicode arguments. From tim_one@users.sourceforge.net Sun Feb 2 07:51:35 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 01 Feb 2003 23:51:35 -0800 Subject: [Python-checkins] python/dist/src/Objects longobject.c,1.151,1.152 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv7771/Objects Modified Files: longobject.c Log Message: long(string, base) now takes time linear in len(string) when base is a power of 2. Enabled the tail end of test_long() in pickletester.py because it no longer takes forever when run from test_pickle.py. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.151 retrieving revision 1.152 diff -C2 -d -r1.151 -r1.152 *** longobject.c 2 Feb 2003 02:57:53 -0000 1.151 --- longobject.c 2 Feb 2003 07:51:32 -0000 1.152 *************** *** 1091,1094 **** --- 1091,1183 ---- } + /* *str points to the first digit in a string of base base digits. base + * is a power of 2 (2, 4, 8, 16, or 32). *str is set to point to the first + * non-digit (which may be *str!). A normalized long is returned. + * The point to this routine is that it takes time linear in the number of + * string characters. + */ + static PyLongObject * + long_from_binary_base(char **str, int base) + { + char *p = *str; + char *start = p; + int bits_per_char; + int n; + PyLongObject *z; + twodigits accum; + int bits_in_accum; + digit *pdigit; + + assert(base >= 2 && base <= 32 && (base & (base - 1)) == 0); + n = base; + for (bits_per_char = -1; n; ++bits_per_char) + n >>= 1; + /* n <- total # of bits needed, while setting p to end-of-string */ + n = 0; + for (;;) { + int k = -1; + char ch = *p; + + if (ch <= '9') + k = ch - '0'; + else if (ch >= 'a') + k = ch - 'a' + 10; + else if (ch >= 'A') + k = ch - 'A' + 10; + if (k < 0 || k >= base) + break; + n += bits_per_char; + if (n < 0) { + PyErr_SetString(PyExc_ValueError, + "long string too large to convert"); + return NULL; + } + ++p; + } + *str = p; + /* n <- # of Python digits needed, = ceiling(n/SHIFT). */ + n = (n + SHIFT - 1) / SHIFT; + z = _PyLong_New(n); + if (z == NULL) + return NULL; + /* Read string from right, and fill in long from left; i.e., + * from least to most significant in both. + */ + accum = 0; + bits_in_accum = 0; + pdigit = z->ob_digit; + while (--p >= start) { + unsigned char ch = (unsigned char)*p; + digit k; + + if (ch <= '9') + k = ch - '0'; + else if (ch >= 'a') + k = ch - 'a' + 10; + else { + assert(ch >= 'A'); + k = ch - 'A' + 10; + } + assert(k >= 0 && k <= base); + accum |= k << bits_in_accum; + bits_in_accum += bits_per_char; + if (bits_in_accum >= SHIFT) { + *pdigit++ = (digit)(accum & MASK); + assert(pdigit - z->ob_digit <= n); + accum >>= SHIFT; + bits_in_accum -= SHIFT; + assert(bits_in_accum < SHIFT); + } + } + if (bits_in_accum) { + assert(bits_in_accum <= SHIFT); + *pdigit++ = (digit)accum; + assert(pdigit - z->ob_digit <= n); + } + while (pdigit - z->ob_digit < n) + *pdigit++ = 0; + return long_normalize(z); + } + PyObject * PyLong_FromString(char *str, char **pend, int base) *************** *** 1123,1143 **** if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) str += 2; - z = _PyLong_New(0); start = str; ! for ( ; z != NULL; ++str) { ! int k = -1; ! PyLongObject *temp; ! if (*str <= '9') ! k = *str - '0'; ! else if (*str >= 'a') ! k = *str - 'a' + 10; ! else if (*str >= 'A') ! k = *str - 'A' + 10; ! if (k < 0 || k >= base) ! break; ! temp = muladd1(z, (digit)base, (digit)k); ! Py_DECREF(z); ! z = temp; } if (z == NULL) --- 1212,1236 ---- if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) str += 2; start = str; ! if ((base & (base - 1)) == 0) ! z = long_from_binary_base(&str, base); ! else { ! z = _PyLong_New(0); ! for ( ; z != NULL; ++str) { ! int k = -1; ! PyLongObject *temp; ! if (*str <= '9') ! k = *str - '0'; ! else if (*str >= 'a') ! k = *str - 'a' + 10; ! else if (*str >= 'A') ! k = *str - 'A' + 10; ! if (k < 0 || k >= base) ! break; ! temp = muladd1(z, (digit)base, (digit)k); ! Py_DECREF(z); ! z = temp; ! } } if (z == NULL) From tim_one@users.sourceforge.net Sun Feb 2 08:05:35 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 02 Feb 2003 00:05:35 -0800 Subject: [Python-checkins] python/dist/src/Objects longobject.c,1.152,1.153 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv10850/Objects Modified Files: longobject.c Log Message: Tightened a too-generous assert. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.152 retrieving revision 1.153 diff -C2 -d -r1.152 -r1.153 *** longobject.c 2 Feb 2003 07:51:32 -0000 1.152 --- longobject.c 2 Feb 2003 08:05:32 -0000 1.153 *************** *** 1159,1163 **** k = ch - 'A' + 10; } ! assert(k >= 0 && k <= base); accum |= k << bits_in_accum; bits_in_accum += bits_per_char; --- 1159,1163 ---- k = ch - 'A' + 10; } ! assert(k < base); accum |= k << bits_in_accum; bits_in_accum += bits_per_char; From davecole@users.sourceforge.net Sun Feb 2 09:59:26 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Sun, 02 Feb 2003 01:59:26 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv10853 Modified Files: csv.py Log Message: Added reply comment to andrewm about lineterminator strangeness. Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** csv.py 31 Jan 2003 21:30:20 -0000 1.8 --- csv.py 2 Feb 2003 09:59:24 -0000 1.9 *************** *** 11,14 **** --- 11,16 ---- # XXX - andrewm - This is causing weird errors from the _csv module - needs # investigation: + # XXX - davecole - I just noticed that I was saving a string arg 's' + # instead of an object arg 'O'. What do you see now? # lineterminator = '\r\n' quoting = QUOTE_MINIMAL From davecole@users.sourceforge.net Sun Feb 2 10:02:42 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Sun, 02 Feb 2003 02:02:42 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv10998 Modified Files: _csv.c Log Message: Change comments which refer to "MS double quote" to doublequote. Fixed stupid bug (introduced while porting Object Craft module) where p.join(['ab"cdef"h']) did not obey doublequote. Fixed PyArg_ParseTupleAndKeywords() type character for lineterminator - was 's', should have been 'O'. Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** _csv.c 30 Jan 2003 13:36:06 -0000 1.4 --- _csv.c 2 Feb 2003 10:02:40 -0000 1.5 *************** *** 212,216 **** else if (c == self->quotechar) { if (self->doublequote) { ! /* microsoft style double quotes; " represented by "" */ self->state = QUOTE_IN_QUOTED_FIELD; } --- 212,216 ---- else if (c == self->quotechar) { if (self->doublequote) { ! /* doublequote; " represented by "" */ self->state = QUOTE_IN_QUOTED_FIELD; } *************** *** 235,239 **** case QUOTE_IN_QUOTED_FIELD: ! /* microsoft double quotes - seen a quote in an quoted field */ if (self->have_quotechar && c == self->quotechar) { /* save "" as " */ --- 235,239 ---- case QUOTE_IN_QUOTED_FIELD: ! /* doublequote - seen a quote in an quoted field */ if (self->have_quotechar && c == self->quotechar) { /* save "" as " */ *************** *** 404,411 **** if (c == '\0') break; ! /* If in MS double quote mode we escape quote chars with a * quote. */ ! if (c == self->have_quotechar && self->doublequote) { if (copy_phase) self->rec[rec_len] = self->quotechar; --- 404,412 ---- if (c == '\0') break; ! /* If in doublequote mode we escape quote chars with a * quote. */ ! if (self->have_quotechar ! && c == self->quotechar && self->doublequote) { if (copy_phase) self->rec[rec_len] = self->quotechar; *************** *** 774,778 **** quotechar = escapechar = NULL; ! if (PyArg_ParseTupleAndKeywords(args, keyword_args, "|OcOisiiii", keywords, "echar, &self->delimiter, --- 775,779 ---- quotechar = escapechar = NULL; ! if (PyArg_ParseTupleAndKeywords(args, keyword_args, "|OcOiOiiii", keywords, "echar, &self->delimiter, From davecole@users.sourceforge.net Sun Feb 2 10:54:01 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Sun, 02 Feb 2003 02:54:01 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv25862 Modified Files: csv.py Log Message: Added QUOTE_NONE - I know I said it wasn't necessary. Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** csv.py 2 Feb 2003 09:59:24 -0000 1.9 --- csv.py 2 Feb 2003 10:53:59 -0000 1.10 *************** *** 2,6 **** from _csv import Error as CSVError ! QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC = range(3) class Dialect: --- 2,6 ---- from _csv import Error as CSVError ! QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE = range(4) class Dialect: From davecole@users.sourceforge.net Sun Feb 2 11:01:51 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Sun, 02 Feb 2003 03:01:51 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv28709 Modified Files: _csv.c Log Message: Implemented all quoting styles. Added code to return quotechar and escapechar as None when have_quotechar and have_escapechar false respectively. Added checks on the values for quoting. Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** _csv.c 2 Feb 2003 10:02:40 -0000 1.5 --- _csv.c 2 Feb 2003 11:01:46 -0000 1.6 *************** *** 25,29 **** typedef enum { ! QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC } QuoteStyle; --- 25,29 ---- typedef enum { ! QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE } QuoteStyle; *************** *** 393,402 **** rec_len++; } ! /* We only know about quoted in the copy phase. */ ! if (copy_phase && *quoted) { ! self->rec[rec_len] = self->quotechar; rec_len++; } for (i = 0;; i++) { char c = field[i]; --- 393,419 ---- rec_len++; } ! /* Handle preceding quote. */ ! switch (self->quoting) { ! case QUOTE_ALL: ! *quoted = 1; ! if (copy_phase) ! self->rec[rec_len] = self->quotechar; rec_len++; + break; + case QUOTE_MINIMAL: + case QUOTE_NONNUMERIC: + /* We only know about quoted in the copy phase. + */ + if (copy_phase && *quoted) { + self->rec[rec_len] = self->quotechar; + rec_len++; + } + break; + case QUOTE_NONE: + break; } + /* Copy/count field data. + */ for (i = 0;; i++) { char c = field[i]; *************** *** 413,417 **** *quoted = 1; rec_len++; ! } /* Some special characters need to be escaped. If we have a * quote character switch to quoted field instead of escaping --- 430,437 ---- *quoted = 1; rec_len++; ! } else if (self->quoting == QUOTE_NONNUMERIC ! && !*quoted && !isdigit(c)) ! *quoted = 1; ! /* Some special characters need to be escaped. If we have a * quote character switch to quoted field instead of escaping *************** *** 421,425 **** && (c == self->delimiter || c == self->escapechar || c == '\n' || c == '\r')) { ! if (self->have_quotechar) *quoted = 1; else if (self->escapechar) { --- 441,446 ---- && (c == self->delimiter || c == self->escapechar || c == '\n' || c == '\r')) { ! if (self->have_quotechar ! && self->quoting != QUOTE_NONE) *quoted = 1; else if (self->escapechar) { *************** *** 428,431 **** --- 449,456 ---- rec_len++; } + else { + raise_exception("delimter must be quoted or escaped"); + return -1; + } } /* Copy field character into record buffer. *************** *** 464,467 **** --- 489,494 ---- quoted = 0; rec_len = join_append_data(self, field, quote_empty, "ed, 0); + if (rec_len < 0) + return 0; /* grow record buffer if necessary */ *************** *** 599,602 **** --- 626,635 ---- PyObject *rv; + if ((strcmp(name, "quotechar") == 0 && !self->have_quotechar) + || (strcmp(name, "escapechar") == 0 && !self->have_escapechar)) { + Py_INCREF(Py_None); + return Py_None; + } + rv = PyMember_Get((char *)self, Parser_memberlist, name); if (rv) *************** *** 615,623 **** if (v == Py_None) { - *attr = 0; - *have_attr = 0; - return 0; - } - else if (PyInt_Check(v) && PyInt_AsLong(v) == 0) { *have_attr = 0; *attr = 0; --- 648,651 ---- *************** *** 642,652 **** return -1; } ! if (strcmp(name, "delimiter") == 0) { ! int have_delimiter; ! ! return _set_char_attr(&self->delimiter, ! &have_delimiter, v); ! } ! else if (strcmp(name, "quotechar") == 0) return _set_char_attr(&self->quotechar, &self->have_quotechar, v); --- 670,674 ---- return -1; } ! if (strcmp(name, "quotechar") == 0) return _set_char_attr(&self->quotechar, &self->have_quotechar, v); *************** *** 654,657 **** --- 676,691 ---- return _set_char_attr(&self->escapechar, &self->have_escapechar, v); + else if (strcmp(name, "quoting") == 0 && PyInt_Check(v)) { + int n = PyInt_AsLong(v); + + if (n < 0 || n > QUOTE_NONE) { + PyErr_BadArgument(); + return -1; + } + if (n == QUOTE_NONE) + self->have_quotechar = 0; + self->quoting = n; + return 0; + } else return PyMember_Set((char *)self, Parser_memberlist, name, v); *************** *** 785,790 **** &self->have_quotechar, quotechar) && !_set_char_attr(&self->escapechar, ! &self->have_escapechar, escapechar)) ! return (PyObject*)self; Py_DECREF(self); --- 819,833 ---- &self->have_quotechar, quotechar) && !_set_char_attr(&self->escapechar, ! &self->have_escapechar, escapechar)) { ! if (self->quoting < 0 || self->quoting > QUOTE_NONE) ! PyErr_SetString(PyExc_ValueError, "bad quoting value"); ! else { ! if (self->quoting == QUOTE_NONE) ! self->have_quotechar = 0; ! else if (!self->have_quotechar) ! self->quoting = QUOTE_NONE; ! return (PyObject*)self; ! } ! } Py_DECREF(self); From davecole@users.sourceforge.net Sun Feb 2 11:06:04 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Sun, 02 Feb 2003 03:06:04 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv350 Modified Files: _csv.c Log Message: Spelling errors in exception text. Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** _csv.c 2 Feb 2003 11:01:46 -0000 1.6 --- _csv.c 2 Feb 2003 11:06:01 -0000 1.7 *************** *** 319,323 **** } self->had_parse_error = 1; ! return raise_exception("Newline inside string"); } if (c == '\n') { --- 319,323 ---- } self->had_parse_error = 1; ! return raise_exception("newline inside string"); } if (c == '\n') { *************** *** 327,331 **** break; self->had_parse_error = 1; ! return raise_exception("Newline inside string"); } parse_process_char(self, c); --- 327,331 ---- break; self->had_parse_error = 1; ! return raise_exception("newline inside string"); } parse_process_char(self, c); *************** *** 450,454 **** } else { ! raise_exception("delimter must be quoted or escaped"); return -1; } --- 450,454 ---- } else { ! raise_exception("delimiter must be quoted or escaped"); return -1; } From davecole@users.sourceforge.net Sun Feb 2 11:14:30 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Sun, 02 Feb 2003 03:14:30 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.7,1.8 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv2429 Modified Files: _csv.c Log Message: Implemented skipinitialspace. Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** _csv.c 2 Feb 2003 11:06:01 -0000 1.7 --- _csv.c 2 Feb 2003 11:14:28 -0000 1.8 *************** *** 163,166 **** --- 163,169 ---- parse_save_field(self); } + else if (c == ' ' && self->skipinitialspace) + /* ignore space at start of field */ + ; else { /* begin new unquoted field */ From davecole@users.sourceforge.net Sun Feb 2 11:55:43 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Sun, 02 Feb 2003 03:55:43 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv11819 Modified Files: _csv.c Log Message: Fixed refcount bug in constructor regarding lineterminator string. Implemented lineterminator functionality - appends lineterminator to end of joined record. Not sure what to do with \n which do not match the lineterminator string... Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** _csv.c 2 Feb 2003 11:14:28 -0000 1.8 --- _csv.c 2 Feb 2003 11:55:41 -0000 1.9 *************** *** 486,499 **** static int ! join_append(ParserObj *self, char *field, int quote_empty) { - int rec_len, quoted; - - quoted = 0; - rec_len = join_append_data(self, field, quote_empty, "ed, 0); - if (rec_len < 0) - return 0; - - /* grow record buffer if necessary */ if (rec_len > self->rec_size) { if (self->rec_size == 0) { --- 486,491 ---- static int ! join_check_rec_size(ParserObj *self, int rec_len) { if (rec_len > self->rec_size) { if (self->rec_size == 0) { *************** *** 514,517 **** --- 506,525 ---- } } + return 1; + } + + static int + join_append(ParserObj *self, char *field, int quote_empty) + { + int rec_len, quoted; + + quoted = 0; + rec_len = join_append_data(self, field, quote_empty, "ed, 0); + if (rec_len < 0) + return 0; + + /* grow record buffer if necessary */ + if (!join_check_rec_size(self, rec_len)) + return 0; self->rec_len = join_append_data(self, field, quote_empty, "ed, 1); *************** *** 521,524 **** --- 529,550 ---- } + static int + join_append_lineterminator(ParserObj *self) + { + int terminator_len; + + terminator_len = PyString_Size(self->lineterminator); + + /* grow record buffer if necessary */ + if (!join_check_rec_size(self, self->rec_len + terminator_len)) + return 0; + + memmove(self->rec + self->rec_len, + PyString_AsString(self->lineterminator), terminator_len); + self->rec_len += terminator_len; + + return 1; + } + static PyObject * join_string(ParserObj *self) *************** *** 548,551 **** --- 574,579 ---- return NULL; + /* Join all fields in internal buffer. + */ join_reset(self); for (i = 0; i < len; i++) { *************** *** 580,583 **** --- 608,616 ---- } + /* Add line terminator. + */ + if (!join_append_lineterminator(self)) + return 0; + return join_string(self); } *************** *** 691,694 **** --- 724,731 ---- return 0; } + else if (strcmp(name, "lineterminator") == 0 && !PyString_Check(v)) { + PyErr_BadArgument(); + return -1; + } else return PyMember_Set((char *)self, Parser_memberlist, name, v); *************** *** 788,792 **** self->have_escapechar = 0; self->skipinitialspace = 0; ! self->lineterminator = PyString_FromString("\r\n"); self->quoting = QUOTE_MINIMAL; self->doublequote = 1; --- 825,829 ---- self->have_escapechar = 0; self->skipinitialspace = 0; ! self->lineterminator = NULL; self->quoting = QUOTE_MINIMAL; self->doublequote = 1; *************** *** 796,799 **** --- 833,841 ---- self->state = START_RECORD; self->fields = PyList_New(0); + if (self->fields == NULL) { + Py_DECREF(self); + return NULL; + } + self->had_parse_error = 0; self->field = NULL; *************** *** 806,816 **** self->num_fields = 0; - if (self->lineterminator == NULL || self->fields == NULL) { - Py_DECREF(self); - return NULL; - } - quotechar = escapechar = NULL; ! if (PyArg_ParseTupleAndKeywords(args, keyword_args, "|OcOiOiiii", keywords, "echar, &self->delimiter, --- 848,853 ---- self->num_fields = 0; quotechar = escapechar = NULL; ! if (PyArg_ParseTupleAndKeywords(args, keyword_args, "|OcOiSiiii", keywords, "echar, &self->delimiter, *************** *** 823,826 **** --- 860,869 ---- && !_set_char_attr(&self->escapechar, &self->have_escapechar, escapechar)) { + if (self->lineterminator == NULL) + self->lineterminator = PyString_FromString("\r\n"); + else { + Py_INCREF(self->lineterminator); + } + if (self->quoting < 0 || self->quoting > QUOTE_NONE) PyErr_SetString(PyExc_ValueError, "bad quoting value"); From davecole@users.sourceforge.net Sun Feb 2 11:57:31 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Sun, 02 Feb 2003 03:57:31 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv12500 Modified Files: csv.py Log Message: Implemented lineterminator in _csv. * Removed append of '\n' in csv.writer.write() * Fixed tests to look for records terminated by '\r\n'. Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** csv.py 2 Feb 2003 10:53:59 -0000 1.10 --- csv.py 2 Feb 2003 11:57:28 -0000 1.11 *************** *** 9,17 **** escapechar = None skipinitialspace = False ! # XXX - andrewm - This is causing weird errors from the _csv module - needs ! # investigation: ! # XXX - davecole - I just noticed that I was saving a string arg 's' ! # instead of an object arg 'O'. What do you see now? ! # lineterminator = '\r\n' quoting = QUOTE_MINIMAL --- 9,13 ---- escapechar = None skipinitialspace = False ! lineterminator = '\r\n' quoting = QUOTE_MINIMAL *************** *** 75,79 **** except (TypeError, AttributeError): pass ! self.fileobj.write(self.parser.join(fields) + '\n') def writelines(self, lines): --- 71,75 ---- except (TypeError, AttributeError): pass ! self.fileobj.write(self.parser.join(fields)) def writelines(self, lines): From davecole@users.sourceforge.net Sun Feb 2 11:57:31 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Sun, 02 Feb 2003 03:57:31 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv12500/test Modified Files: test_csv.py Log Message: Implemented lineterminator in _csv. * Removed append of '\n' in csv.writer.write() * Fixed tests to look for records terminated by '\r\n'. Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_csv.py 31 Jan 2003 21:30:43 -0000 1.3 --- test_csv.py 2 Feb 2003 11:57:28 -0000 1.4 *************** *** 98,114 **** def test_single(self): ! self.writerAssertEqual([['abc']], 'abc\n') def test_simple(self): ! self.writerAssertEqual([[1, 2, 'abc', 3, 4]], '1,2,abc,3,4\n') def test_quotes(self): ! self.writerAssertEqual([[1, 2, 'a"bc"', 3, 4]], '1,2,"a""bc""",3,4\n') def test_quote_fieldsep(self): ! self.writerAssertEqual([['abc,def']], '"abc,def"\n') def test_newlines(self): ! self.writerAssertEqual([[1, 2, 'a\nbc', 3, 4]], '1,2,"a\nbc",3,4\n') class TestDictFields(unittest.TestCase): --- 98,114 ---- def test_single(self): ! self.writerAssertEqual([['abc']], 'abc\r\n') def test_simple(self): ! self.writerAssertEqual([[1, 2, 'abc', 3, 4]], '1,2,abc,3,4\r\n') def test_quotes(self): ! self.writerAssertEqual([[1, 2, 'a"bc"', 3, 4]], '1,2,"a""bc""",3,4\r\n') def test_quote_fieldsep(self): ! self.writerAssertEqual([['abc,def']], '"abc,def"\r\n') def test_newlines(self): ! self.writerAssertEqual([[1, 2, 'a\nbc', 3, 4]], '1,2,"a\nbc",3,4\r\n') class TestDictFields(unittest.TestCase): *************** *** 118,122 **** fieldnames = ["f1", "f2", "f3"]) writer.write({"f1": 10, "f3": "abc"}) ! self.assertEqual(fileobj.getvalue(), "10,,abc\n") def test_no_fields(self): --- 118,122 ---- fieldnames = ["f1", "f2", "f3"]) writer.write({"f1": 10, "f3": "abc"}) ! self.assertEqual(fileobj.getvalue(), "10,,abc\r\n") def test_no_fields(self): From davecole@users.sourceforge.net Sun Feb 2 12:05:10 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Sun, 02 Feb 2003 04:05:10 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv14624 Modified Files: csv.py Log Message: Added doublequote to the default Dialect and reordered parameters to match the documentation in _csv. Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** csv.py 2 Feb 2003 11:57:28 -0000 1.11 --- csv.py 2 Feb 2003 12:05:07 -0000 1.12 *************** *** 5,11 **** class Dialect: - quotechar = '"' delimiter = ',' escapechar = None skipinitialspace = False lineterminator = '\r\n' --- 5,12 ---- class Dialect: delimiter = ',' + quotechar = '"' escapechar = None + doublequote = True skipinitialspace = False lineterminator = '\r\n' From davecole@users.sourceforge.net Sun Feb 2 12:16:28 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Sun, 02 Feb 2003 04:16:28 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.9,1.10 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv17084 Modified Files: _csv.c Log Message: Oops - forgot to check for '+-.' when quoting is QUOTE_NONNUMERIC. Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** _csv.c 2 Feb 2003 11:55:41 -0000 1.9 --- _csv.c 2 Feb 2003 12:16:26 -0000 1.10 *************** *** 433,438 **** *quoted = 1; rec_len++; ! } else if (self->quoting == QUOTE_NONNUMERIC ! && !*quoted && !isdigit(c)) *quoted = 1; --- 433,438 ---- *quoted = 1; rec_len++; ! } else if (self->quoting == QUOTE_NONNUMERIC && !*quoted ! && !(isdigit(c) || c == '+' || c == '-' || c == '.')) *quoted = 1; From davecole@users.sourceforge.net Sun Feb 2 12:25:26 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Sun, 02 Feb 2003 04:25:26 -0800 Subject: [Python-checkins] python/nondist/peps pep-0305.txt,1.9,1.10 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv18578 Modified Files: pep-0305.txt Log Message: Changed the csv.reader() fileobj argument to interable. This give us much more flexibility in processing filtered data. Made the example excel dialect match the dialect in csv.py. Added explanation of doublequote. Added explanation of csv.QUOTE_NONE. Index: pep-0305.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0305.txt,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** pep-0305.txt 31 Jan 2003 21:55:38 -0000 1.9 --- pep-0305.txt 2 Feb 2003 12:25:23 -0000 1.10 *************** *** 90,98 **** writing. The basic reading interface is:: ! obj = reader(fileobj [, dialect='excel2000'] [optional keyword args]) ! A reader object is an iterable which takes a file-like object opened ! for reading as the sole required parameter. The optional dialect parameter is discussed below. It also accepts several optional keyword arguments which define specific format settings for the parser --- 90,98 ---- writing. The basic reading interface is:: ! obj = reader(iterable [, dialect='excel2000'] [optional keyword args]) ! A reader object is an iterable which takes an interable object which ! returns lines as the sole required parameter. The optional dialect parameter is discussed below. It also accepts several optional keyword arguments which define specific format settings for the parser *************** *** 154,160 **** class excel: - quotechar = '"' delimiter = ',' escapechar = None skipinitialspace = False lineterminator = '\r\n' --- 154,161 ---- class excel: delimiter = ',' + quotechar = '"' escapechar = None + doublequote = True skipinitialspace = False lineterminator = '\r\n' *************** *** 189,198 **** - ``quotechar`` specifies a one-character string to use as the quoting ! character. It defaults to '"'. - ``delimiter`` specifies a one-character string to use as the field separator. It defaults to ','. ! - ``escapechar`` specifies a one character string used to escape the delimiter when quotechar is set to None. --- 190,200 ---- - ``quotechar`` specifies a one-character string to use as the quoting ! character. It defaults to '"'. Setting this to None has the same ! effect as setting quoting to csv.QUOTE_NONE. - ``delimiter`` specifies a one-character string to use as the field separator. It defaults to ','. ! - ``escapechar`` specifies a one-character string used to escape the delimiter when quotechar is set to None. *************** *** 216,220 **** fields which contain characters other than [+-0-9.]. ! - ``doublequote`` (tbd) - are there more to come? --- 218,227 ---- fields which contain characters other than [+-0-9.]. ! csv.QUOTE_NONE means that quotes are never placed around ! fields. ! ! - ``doublequote`` controls the handling of quotes inside fields. When ! True two consecutive quotes are interpreted as one during read, and ! when writing, each quote is written as two quotes. - are there more to come? From davecole@users.sourceforge.net Sun Feb 2 12:58:42 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Sun, 02 Feb 2003 04:58:42 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.10,1.11 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv27784 Modified Files: _csv.c Log Message: Better use of METH_ flags. Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** _csv.c 2 Feb 2003 12:16:26 -0000 1.10 --- _csv.c 2 Feb 2003 12:58:40 -0000 1.11 *************** *** 357,365 **** static PyObject * ! Parser_clear(ParserObj *self, PyObject *args) { - if (!PyArg_ParseTuple(args, "")) - return NULL; - clear_fields_and_status(self); --- 357,362 ---- static PyObject * ! Parser_clear(ParserObj *self) { clear_fields_and_status(self); *************** *** 560,570 **** static PyObject * ! Parser_join(ParserObj *self, PyObject *args) { - PyObject *seq; int len, i; - if (!PyArg_ParseTuple(args, "O", &seq)) - return NULL; if (!PySequence_Check(seq)) return raise_exception("sequence expected"); --- 557,564 ---- static PyObject * ! Parser_join(ParserObj *self, PyObject *seq) { int len, i; if (!PySequence_Check(seq)) return raise_exception("sequence expected"); *************** *** 619,625 **** { "parse", (PyCFunction)Parser_parse, METH_VARARGS, Parser_parse_doc }, ! { "clear", (PyCFunction)Parser_clear, METH_VARARGS, Parser_clear_doc }, ! { "join", (PyCFunction)Parser_join, METH_VARARGS, Parser_join_doc }, { NULL, NULL } --- 613,619 ---- { "parse", (PyCFunction)Parser_parse, METH_VARARGS, Parser_parse_doc }, ! { "clear", (PyCFunction)Parser_clear, METH_NOARGS, Parser_clear_doc }, ! { "join", (PyCFunction)Parser_join, METH_O, Parser_join_doc }, { NULL, NULL } From rhettinger@users.sourceforge.net Sun Feb 2 14:27:21 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 02 Feb 2003 06:27:21 -0800 Subject: [Python-checkins] python/dist/src/Lib sets.py,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv25238 Modified Files: sets.py Log Message: SF patch #678899: Save time and memory by using itertools in sets module. Index: sets.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sets.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** sets.py 14 Jan 2003 16:40:06 -0000 1.37 --- sets.py 2 Feb 2003 14:27:19 -0000 1.38 *************** *** 58,62 **** __all__ = ['BaseSet', 'Set', 'ImmutableSet'] ! class BaseSet(object): --- 58,62 ---- __all__ = ['BaseSet', 'Set', 'ImmutableSet'] ! from itertools import ifilter class BaseSet(object): *************** *** 183,187 **** else: little, big = other, self ! common = filter(big._data.has_key, little._data) return self.__class__(common) --- 183,187 ---- else: little, big = other, self ! common = ifilter(big._data.has_key, little) return self.__class__(common) *************** *** 205,214 **** selfdata = self._data otherdata = other._data ! for elt in selfdata: ! if elt not in otherdata: ! data[elt] = value ! for elt in otherdata: ! if elt not in selfdata: ! data[elt] = value return result --- 205,212 ---- selfdata = self._data otherdata = other._data ! for elt in ifilter(otherdata.has_key, selfdata, True): ! data[elt] = value ! for elt in ifilter(selfdata.has_key, otherdata, True): ! data[elt] = value return result *************** *** 229,237 **** result = self.__class__() data = result._data - otherdata = other._data value = True ! for elt in self: ! if elt not in otherdata: ! data[elt] = value return result --- 227,233 ---- result = self.__class__() data = result._data value = True ! for elt in ifilter(other._data.has_key, self, True): ! data[elt] = value return result *************** *** 265,272 **** if len(self) > len(other): # Fast check for obvious cases return False ! otherdata = other._data ! for elt in self: ! if elt not in otherdata: ! return False return True --- 261,266 ---- if len(self) > len(other): # Fast check for obvious cases return False ! for elt in ifilter(other._data.has_key, self, True): ! return False return True *************** *** 276,282 **** if len(self) < len(other): # Fast check for obvious cases return False ! selfdata = self._data ! for elt in other: ! if elt not in selfdata: return False return True --- 270,274 ---- if len(self) < len(other): # Fast check for obvious cases return False ! for elt in ifilter(self._data.has_key, other, True): return False return True From rhettinger@users.sourceforge.net Sun Feb 2 16:07:55 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 02 Feb 2003 08:07:55 -0800 Subject: [Python-checkins] python/dist/src/Lib sets.py,1.38,1.39 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv7462 Modified Files: sets.py Log Message: One more use of ifilter() Index: sets.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sets.py,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** sets.py 2 Feb 2003 14:27:19 -0000 1.38 --- sets.py 2 Feb 2003 16:07:53 -0000 1.39 *************** *** 437,443 **** self._binary_sanity_check(other) data = self._data ! for elt in other: ! if elt in data: ! del data[elt] return self --- 437,442 ---- self._binary_sanity_check(other) data = self._data ! for elt in ifilter(data.has_key, other): ! del data[elt] return self From tim_one@users.sourceforge.net Sun Feb 2 16:09:07 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 02 Feb 2003 08:09:07 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv6130/Lib/test Modified Files: pickletester.py Log Message: Add cPickle support for PROTO. Duplicated PROTO/LONG1/LONG4 code in the hitherto unknown (to me) noload() cPickle function, which is (a) something we don't test at all, and (b) pickle.py doesn't have. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** pickletester.py 2 Feb 2003 07:51:32 -0000 1.33 --- pickletester.py 2 Feb 2003 16:09:05 -0000 1.34 *************** *** 1,3 **** --- 1,5 ---- import unittest + import pickle + from test.test_support import TestFailed, have_unicode, TESTFN *************** *** 297,300 **** --- 299,321 ---- # Tests for protocol 2 + def test_proto(self): + build_none = pickle.NONE + pickle.STOP + for proto in protocols: + expected = build_none + if proto >= 2: + expected = pickle.PROTO + chr(proto) + expected + p = self.dumps(None, proto) + self.assertEqual(p, expected) + + oob = protocols[-1] + 1 # a future protocol + badpickle = pickle.PROTO + chr(oob) + build_none + try: + self.loads(badpickle) + except ValueError, detail: + self.failUnless(str(detail).startswith( + "unsupported pickle protocol")) + else: + self.fail("expected bad protocol number to raise ValueError") + def test_long1(self): x = 12345678910111213141516178920L *************** *** 315,319 **** d = (1, 2, 3) e = (1, 2, 3, 4) ! for proto in 0, 1, 2: for x in a, b, c, d, e: s = self.dumps(x, proto) --- 336,340 ---- d = (1, 2, 3) e = (1, 2, 3, 4) ! for proto in protocols: for x in a, b, c, d, e: s = self.dumps(x, proto) *************** *** 322,326 **** def test_singletons(self): ! for proto in 0, 1, 2: for x in None, False, True: s = self.dumps(x, proto) --- 343,347 ---- def test_singletons(self): ! for proto in protocols: for x in None, False, True: s = self.dumps(x, proto) From tim_one@users.sourceforge.net Sun Feb 2 16:09:08 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 02 Feb 2003 08:09:08 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.107,2.108 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv6130/Modules Modified Files: cPickle.c Log Message: Add cPickle support for PROTO. Duplicated PROTO/LONG1/LONG4 code in the hitherto unknown (to me) noload() cPickle function, which is (a) something we don't test at all, and (b) pickle.py doesn't have. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.107 retrieving revision 2.108 diff -C2 -d -r2.107 -r2.108 *** cPickle.c 2 Feb 2003 02:57:52 -0000 2.107 --- cPickle.c 2 Feb 2003 16:09:05 -0000 2.108 *************** *** 2214,2224 **** static char stop = STOP; if (save(self, args, 0) < 0) return -1; ! if ((*self->write_func)(self, &stop, 1) < 0) return -1; ! if ((*self->write_func)(self, NULL, 0) < 0) return -1; --- 2214,2233 ---- static char stop = STOP; + if (self->proto >= 2) { + char bytes[2]; + + bytes[0] = PROTO; + bytes[1] = CURRENT_PROTOCOL_NUMBER; + if (self->write_func(self, bytes, 2) < 0) + return -1; + } + if (save(self, args, 0) < 0) return -1; ! if (self->write_func(self, &stop, 1) < 0) return -1; ! if (self->write_func(self, NULL, 0) < 0) return -1; *************** *** 3871,3874 **** --- 3880,3908 ---- } + /* Just raises an error if we don't know the protocol specified. PROTO + * is the first opcode for protocols >= 2. + */ + static int + load_proto(Unpicklerobject *self) + { + int i; + char *protobyte; + + i = self->read_func(self, &protobyte, 1); + if (i < 0) + return -1; + + i = calc_binint(protobyte, 1); + /* No point checking for < 0, since calc_binint returns an unsigned + * int when chewing on 1 byte. + */ + assert(i >= 0); + if (i <= CURRENT_PROTOCOL_NUMBER) + return 0; + + PyErr_Format(PyExc_ValueError, "unsupported pickle protocol: %d", i); + return -1; + } + static PyObject * load(Unpicklerobject *self) *************** *** 4100,4103 **** --- 4134,4142 ---- continue; + case PROTO: + if (load_proto(self) < 0) + break; + continue; + case '\0': /* end of file */ *************** *** 4228,4231 **** --- 4267,4280 ---- continue; + case LONG1: + if (load_counted_long(self, 1) < 0) + break; + continue; + + case LONG4: + if (load_counted_long(self, 4) < 0) + break; + continue; + case FLOAT: if (load_float(self) < 0) *************** *** 4400,4403 **** --- 4449,4457 ---- case REDUCE: if (noload_reduce(self) < 0) + break; + continue; + + case PROTO: + if (load_proto(self) < 0) break; continue; From tim_one@users.sourceforge.net Sun Feb 2 16:14:25 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 02 Feb 2003 08:14:25 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.108,2.109 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv10796/Modules Modified Files: cPickle.c Log Message: dump(): Fixed a stupid bug in new code. It wasn't possible for the bug to have an effect before protocol 3 is invented, so no test can be written for this (yet). Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.108 retrieving revision 2.109 diff -C2 -d -r2.108 -r2.109 *** cPickle.c 2 Feb 2003 16:09:05 -0000 2.108 --- cPickle.c 2 Feb 2003 16:14:23 -0000 2.109 *************** *** 2218,2222 **** bytes[0] = PROTO; ! bytes[1] = CURRENT_PROTOCOL_NUMBER; if (self->write_func(self, bytes, 2) < 0) return -1; --- 2218,2222 ---- bytes[0] = PROTO; ! bytes[1] = self->proto; if (self->write_func(self, bytes, 2) < 0) return -1; From tim_one@users.sourceforge.net Sun Feb 2 16:16:32 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 02 Feb 2003 08:16:32 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.109,2.110 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv13585/Modules Modified Files: cPickle.c Log Message: dump(): Added asserts that self->proto is sane. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.109 retrieving revision 2.110 diff -C2 -d -r2.109 -r2.110 *** cPickle.c 2 Feb 2003 16:14:23 -0000 2.109 --- cPickle.c 2 Feb 2003 16:16:30 -0000 2.110 *************** *** 2218,2222 **** bytes[0] = PROTO; ! bytes[1] = self->proto; if (self->write_func(self, bytes, 2) < 0) return -1; --- 2218,2223 ---- bytes[0] = PROTO; ! assert(self->proto >= 0 && self->proto < 256); ! bytes[1] = (char)self->proto; if (self->write_func(self, bytes, 2) < 0) return -1; From nnorwitz@users.sourceforge.net Sun Feb 2 17:08:35 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 02 Feb 2003 09:08:35 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.110,2.111 _ssl.c,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv13868/Modules Modified Files: cPickle.c _ssl.c Log Message: Fix compiler warning Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.110 retrieving revision 2.111 diff -C2 -d -r2.110 -r2.111 *** cPickle.c 2 Feb 2003 16:16:30 -0000 2.110 --- cPickle.c 2 Feb 2003 17:08:32 -0000 2.111 *************** *** 2917,2921 **** else { /* Read the raw little-endian bytes & convert. */ ! i = self->read_func(self, &(char *)pdata, size); if (i < 0) return -1; along = _PyLong_FromByteArray(pdata, (size_t)size, --- 2917,2921 ---- else { /* Read the raw little-endian bytes & convert. */ ! i = self->read_func(self, (char **)&pdata, size); if (i < 0) return -1; along = _PyLong_FromByteArray(pdata, (size_t)size, Index: _ssl.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_ssl.c,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** _ssl.c 31 Jan 2003 18:13:18 -0000 1.10 --- _ssl.c 2 Feb 2003 17:08:33 -0000 1.11 *************** *** 65,68 **** --- 65,69 ---- static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args); static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args); + static int wait_for_timeout(PySocketSockObject *s, int writing); #define PySSLObject_Check(v) ((v)->ob_type == &PySSL_Type) From nnorwitz@users.sourceforge.net Sun Feb 2 17:10:07 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 02 Feb 2003 09:10:07 -0800 Subject: [Python-checkins] python/dist/src/Misc AIX-NOTES,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv14490a/Misc Modified Files: AIX-NOTES Log Message: Add some notes that got python to work on the snake farm Index: AIX-NOTES =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/AIX-NOTES,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** AIX-NOTES 26 Oct 2000 17:07:01 -0000 1.9 --- AIX-NOTES 2 Feb 2003 17:10:04 -0000 1.10 *************** *** 138,140 **** --- 138,156 ---- for ld_so_aix. + According to Gary Hook from IBM, the format of the export file changed + in AIX 4.2. For AIX 4.2 and later, a period "." is required on the + first line after "#!". If python crashes while importing a shared + library, you can try modifying the LINKCC variable in the Makefile. + It probably looks like this: + + LINKCC= $(srcdir)/Modules/makexp_aix Modules/python.exp \"\" $(LIBRARY); $(PURIFY) $(CXX) + + You should modify the \"\" to be a period: + + LINKCC= $(srcdir)/Modules/makexp_aix Modules/python.exp . $(LIBRARY); $(PURIFY) $(CXX) + + Using a period fixed the problem in the snake farm. YMMV. + After testing with different versions of AIX, a fix should + be checked in. Hopefully, this fix be incorporated into Python 2.3. + ============================================================================== From tim_one@users.sourceforge.net Sun Feb 2 17:26:42 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 02 Feb 2003 09:26:42 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.111,2.112 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv22945/Modules Modified Files: cPickle.c Log Message: Beefed up the tests by putting in more "for proto in protocols:" outer loops. Renamed DATA and BINDATA to DATA0 and DATA1. Included disassemblies, but noted why we can't test them. Added XXX comment to cPickle about a mysterious comment, where pickle and cPickle diverge in how they number PUT indices. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.111 retrieving revision 2.112 diff -C2 -d -r2.111 -r2.112 *** cPickle.c 2 Feb 2003 17:08:32 -0000 2.111 --- cPickle.c 2 Feb 2003 17:26:40 -0000 2.112 *************** *** 720,723 **** --- 720,728 ---- /* Make sure memo keys are positive! */ + /* XXX Why? + * XXX And does "positive" really mean non-negative? + * XXX pickle.py starts with PUT index 0, not 1. This makes for + * XXX gratuitous differences between the pickling modules. + */ p++; From tim_one@users.sourceforge.net Sun Feb 2 17:26:42 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 02 Feb 2003 09:26:42 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv22945/Lib/test Modified Files: pickletester.py Log Message: Beefed up the tests by putting in more "for proto in protocols:" outer loops. Renamed DATA and BINDATA to DATA0 and DATA1. Included disassemblies, but noted why we can't test them. Added XXX comment to cPickle about a mysterious comment, where pickle and cPickle diverge in how they number PUT indices. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** pickletester.py 2 Feb 2003 16:09:05 -0000 1.34 --- pickletester.py 2 Feb 2003 17:26:39 -0000 1.35 *************** *** 36,44 **** __metaclass__ = metaclass ! # DATA and BINDATA are the protocol 0 and protocol 1 pickles of the object ! # returned by create_data(). # break into multiple strings to avoid confusing font-lock-mode ! DATA = """(lp1 I0 aL1L --- 36,45 ---- __metaclass__ = metaclass ! # DATA0 .. DATA2 are the pickles we expect under the various protocols, for ! # the object returned by create_data(). ! # XXX DATA2 doesn't exist yet, as it's not fully implemented in cPickle. # break into multiple strings to avoid confusing font-lock-mode ! DATA0 = """(lp1 I0 aL1L *************** *** 85,96 **** """ ! BINDATA = ']q\x01(K\x00L1L\nG@\x00\x00\x00\x00\x00\x00\x00' + \ ! 'c__builtin__\ncomplex\nq\x02(G@\x08\x00\x00\x00\x00\x00' + \ ! '\x00G\x00\x00\x00\x00\x00\x00\x00\x00tRq\x03K\x01J\xff\xff' + \ ! '\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xff' + \ ! 'J\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00' + \ ! '\x00\x80J\x00\x00\x00\x80(U\x03abcq\x04h\x04(c__main__\n' + \ ! 'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh' + \ ! '\x06tq\nh\nK\x05e.' def create_data(): --- 86,228 ---- """ ! # Disassembly of DATA0. ! DATA0_DIS = """\ ! 0: ( MARK ! 1: l LIST (MARK at 0) ! 2: p PUT 1 ! 5: I INT 0 ! 8: a APPEND ! 9: L LONG 1L ! 13: a APPEND ! 14: F FLOAT 2.0 ! 17: a APPEND ! 18: c GLOBAL '__builtin__ complex' ! 39: p PUT 2 ! 42: ( MARK ! 43: F FLOAT 3.0 ! 46: F FLOAT 0.0 ! 49: t TUPLE (MARK at 42) ! 50: R REDUCE ! 51: p PUT 3 ! 54: a APPEND ! 55: I INT 1 ! 58: a APPEND ! 59: I INT -1 ! 63: a APPEND ! 64: I INT 255 ! 69: a APPEND ! 70: I INT -255 ! 76: a APPEND ! 77: I INT -256 ! 83: a APPEND ! 84: I INT 65535 ! 91: a APPEND ! 92: I INT -65535 ! 100: a APPEND ! 101: I INT -65536 ! 109: a APPEND ! 110: I INT 2147483647 ! 122: a APPEND ! 123: I INT -2147483647 ! 136: a APPEND ! 137: I INT -2147483648 ! 150: a APPEND ! 151: ( MARK ! 152: S STRING 'abc' ! 159: p PUT 4 ! 162: g GET 4 ! 165: ( MARK ! 166: i INST '__main__ C' (MARK at 165) ! 178: p PUT 5 ! 181: ( MARK ! 182: d DICT (MARK at 181) ! 183: p PUT 6 ! 186: S STRING 'foo' ! 193: p PUT 7 ! 196: I INT 1 ! 199: s SETITEM ! 200: S STRING 'bar' ! 207: p PUT 8 ! 210: I INT 2 ! 213: s SETITEM ! 214: b BUILD ! 215: g GET 5 ! 218: t TUPLE (MARK at 151) ! 219: p PUT 9 ! 222: a APPEND ! 223: g GET 9 ! 226: a APPEND ! 227: I INT 5 ! 230: a APPEND ! 231: . STOP ! highest protocol among opcodes = 0 ! """ ! ! DATA1 = (']q\x01(K\x00L1L\nG@\x00\x00\x00\x00\x00\x00\x00' ! 'c__builtin__\ncomplex\nq\x02(G@\x08\x00\x00\x00\x00\x00' ! '\x00G\x00\x00\x00\x00\x00\x00\x00\x00tRq\x03K\x01J\xff\xff' ! '\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xff' ! 'J\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00' ! '\x00\x80J\x00\x00\x00\x80(U\x03abcq\x04h\x04(c__main__\n' ! 'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh' ! '\x06tq\nh\nK\x05e.' ! ) ! ! # Disassembly of DATA1. ! DATA1_DIS = """\ ! 0: ] EMPTY_LIST ! 1: q BINPUT 1 ! 3: ( MARK ! 4: K BININT1 0 ! 6: L LONG 1L ! 10: G BINFLOAT 2.0 ! 19: c GLOBAL '__builtin__ complex' ! 40: q BINPUT 2 ! 42: ( MARK ! 43: G BINFLOAT 3.0 ! 52: G BINFLOAT 0.0 ! 61: t TUPLE (MARK at 42) ! 62: R REDUCE ! 63: q BINPUT 3 ! 65: K BININT1 1 ! 67: J BININT -1 ! 72: K BININT1 255 ! 74: J BININT -255 ! 79: J BININT -256 ! 84: M BININT2 65535 ! 87: J BININT -65535 ! 92: J BININT -65536 ! 97: J BININT 2147483647 ! 102: J BININT -2147483647 ! 107: J BININT -2147483648 ! 112: ( MARK ! 113: U SHORT_BINSTRING 'abc' ! 118: q BINPUT 4 ! 120: h BINGET 4 ! 122: ( MARK ! 123: c GLOBAL '__main__ C' ! 135: q BINPUT 5 ! 137: o OBJ (MARK at 122) ! 138: q BINPUT 6 ! 140: } EMPTY_DICT ! 141: q BINPUT 7 ! 143: ( MARK ! 144: U SHORT_BINSTRING 'foo' ! 149: q BINPUT 8 ! 151: K BININT1 1 ! 153: U SHORT_BINSTRING 'bar' ! 158: q BINPUT 9 ! 160: K BININT1 2 ! 162: u SETITEMS (MARK at 143) ! 163: b BUILD ! 164: h BINGET 6 ! 166: t TUPLE (MARK at 112) ! 167: q BINPUT 10 ! 169: h BINGET 10 ! 171: K BININT1 5 ! 173: e APPENDS (MARK at 3) ! 174: . STOP ! highest protocol among opcodes = 1 ! """ def create_data(): *************** *** 115,186 **** class AbstractPickleTests(unittest.TestCase): _testdata = create_data() def setUp(self): - # subclass must define self.dumps, self.loads, self.error pass def test_misc(self): # test various datatypes not tested by testdata ! x = myint(4) ! s = self.dumps(x) ! y = self.loads(s) ! self.assertEqual(x, y) ! x = (1, ()) ! s = self.dumps(x) ! y = self.loads(s) ! self.assertEqual(x, y) ! x = initarg(1, x) ! s = self.dumps(x) ! y = self.loads(s) ! self.assertEqual(x, y) # XXX test __reduce__ protocol? ! def test_identity(self): ! s = self.dumps(self._testdata) ! x = self.loads(s) ! self.assertEqual(x, self._testdata) ! def test_constant(self): ! x = self.loads(DATA) ! self.assertEqual(x, self._testdata) ! x = self.loads(BINDATA) ! self.assertEqual(x, self._testdata) ! def test_binary(self): ! s = self.dumps(self._testdata, 1) ! x = self.loads(s) ! self.assertEqual(x, self._testdata) def test_recursive_list(self): l = [] l.append(l) ! s = self.dumps(l) ! x = self.loads(s) ! self.assertEqual(x, l) ! self.assertEqual(x, x[0]) ! self.assertEqual(id(x), id(x[0])) def test_recursive_dict(self): d = {} d[1] = d ! s = self.dumps(d) ! x = self.loads(s) ! self.assertEqual(x, d) ! self.assertEqual(x[1], x) ! self.assertEqual(id(x[1]), id(x)) def test_recursive_inst(self): i = C() i.attr = i ! s = self.dumps(i) ! x = self.loads(s) ! self.assertEqual(x, i) ! self.assertEqual(x.attr, x) ! self.assertEqual(id(x.attr), id(x)) def test_recursive_multi(self): --- 247,336 ---- class AbstractPickleTests(unittest.TestCase): + # Subclass must define self.dumps, self.loads, self.error. _testdata = create_data() def setUp(self): pass def test_misc(self): # test various datatypes not tested by testdata ! for proto in protocols: ! x = myint(4) ! s = self.dumps(x, proto) ! y = self.loads(s) ! self.assertEqual(x, y) ! x = (1, ()) ! s = self.dumps(x, proto) ! y = self.loads(s) ! self.assertEqual(x, y) ! x = initarg(1, x) ! s = self.dumps(x, proto) ! y = self.loads(s) ! self.assertEqual(x, y) # XXX test __reduce__ protocol? ! def test_roundtrip_equality(self): ! expected = self._testdata ! for proto in protocols: ! s = self.dumps(expected, proto) ! got = self.loads(s) ! self.assertEqual(expected, got) ! def test_load_from_canned_string(self): ! expected = self._testdata ! for canned in DATA0, DATA1: ! got = self.loads(canned) ! self.assertEqual(expected, got) ! # There are gratuitous differences between pickles produced by ! # pickle and cPickle, largely because cPickle starts PUT indices at ! # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() -- ! # there's a comment with an exclamation point there whose meaning ! # is a mystery. cPickle also suppresses PUT for objects with a refcount ! # of 1. ! def dont_test_disassembly(self): ! from cStringIO import StringIO ! from pickletools import dis ! ! for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS): ! s = self.dumps(self._testdata, proto) ! filelike = StringIO() ! dis(s, out=filelike) ! got = filelike.getvalue() ! self.assertEqual(expected, got) def test_recursive_list(self): l = [] l.append(l) ! for proto in protocols: ! s = self.dumps(l, proto) ! x = self.loads(s) ! self.assertEqual(x, l) ! self.assertEqual(x, x[0]) ! self.assertEqual(id(x), id(x[0])) def test_recursive_dict(self): d = {} d[1] = d ! for proto in protocols: ! s = self.dumps(d, proto) ! x = self.loads(s) ! self.assertEqual(x, d) ! self.assertEqual(x[1], x) ! self.assertEqual(id(x[1]), id(x)) def test_recursive_inst(self): i = C() i.attr = i ! for proto in protocols: ! s = self.dumps(i, 2) ! x = self.loads(s) ! self.assertEqual(x, i) ! self.assertEqual(x.attr, x) ! self.assertEqual(id(x.attr), id(x)) def test_recursive_multi(self): *************** *** 190,201 **** i.attr = d l.append(i) ! s = self.dumps(l) ! x = self.loads(s) ! self.assertEqual(x, l) ! self.assertEqual(x[0], i) ! self.assertEqual(x[0].attr, d) ! self.assertEqual(x[0].attr[1], x) ! self.assertEqual(x[0].attr[1][0], i) ! self.assertEqual(x[0].attr[1][0].attr, d) def test_garyp(self): --- 340,352 ---- i.attr = d l.append(i) ! for proto in protocols: ! s = self.dumps(l, proto) ! x = self.loads(s) ! self.assertEqual(x, l) ! self.assertEqual(x[0], i) ! self.assertEqual(x[0].attr, d) ! self.assertEqual(x[0].attr[1], x) ! self.assertEqual(x[0].attr[1][0], i) ! self.assertEqual(x[0].attr[1][0].attr, d) def test_garyp(self): *************** *** 275,299 **** def test_metaclass(self): a = use_metaclass() ! s = self.dumps(a) ! b = self.loads(s) ! self.assertEqual(a.__class__, b.__class__) def test_structseq(self): import time - t = time.localtime() - s = self.dumps(t) - u = self.loads(s) - self.assertEqual(t, u) import os ! if hasattr(os, "stat"): ! t = os.stat(os.curdir) ! s = self.dumps(t) ! u = self.loads(s) ! self.assertEqual(t, u) ! if hasattr(os, "statvfs"): ! t = os.statvfs(os.curdir) ! s = self.dumps(t) u = self.loads(s) self.assertEqual(t, u) # Tests for protocol 2 --- 426,453 ---- def test_metaclass(self): a = use_metaclass() ! for proto in protocols: ! s = self.dumps(a, proto) ! b = self.loads(s) ! self.assertEqual(a.__class__, b.__class__) def test_structseq(self): import time import os ! ! t = time.localtime() ! for proto in protocols: ! s = self.dumps(t, proto) u = self.loads(s) self.assertEqual(t, u) + if hasattr(os, "stat"): + t = os.stat(os.curdir) + s = self.dumps(t, proto) + u = self.loads(s) + self.assertEqual(t, u) + if hasattr(os, "statvfs"): + t = os.statvfs(os.curdir) + s = self.dumps(t, proto) + u = self.loads(s) + self.assertEqual(t, u) # Tests for protocol 2 *************** *** 357,363 **** self.assertEqual(tuple(x), tuple(y)) self.assertEqual(x.__dict__, y.__dict__) - ## import pickletools - ## print - ## pickletools.dis(s) def test_newobj_list(self): --- 511,514 ---- *************** *** 369,375 **** self.assertEqual(list(x), list(y)) self.assertEqual(x.__dict__, y.__dict__) - ## import pickletools - ## print - ## pickletools.dis(s) def test_newobj_generic(self): --- 520,523 ---- *************** *** 380,386 **** x.foo = 42 s = self.dumps(x, proto) - ## import pickletools - ## print - ## pickletools.dis(s) y = self.loads(s) detail = (proto, C, B, x, y, type(y)) --- 528,531 ---- From tim_one@users.sourceforge.net Sun Feb 2 17:33:55 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 02 Feb 2003 09:33:55 -0800 Subject: [Python-checkins] python/dist/src/Objects longobject.c,1.153,1.154 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv26400/Objects Modified Files: longobject.c Log Message: long_from_binary_base(): Sped this a little by computing the # of bits needed outside the first loop. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.153 retrieving revision 1.154 diff -C2 -d -r1.153 -r1.154 *** longobject.c 2 Feb 2003 08:05:32 -0000 1.153 --- longobject.c 2 Feb 2003 17:33:53 -0000 1.154 *************** *** 1127,1139 **** if (k < 0 || k >= base) break; - n += bits_per_char; - if (n < 0) { - PyErr_SetString(PyExc_ValueError, - "long string too large to convert"); - return NULL; - } ++p; } *str = p; /* n <- # of Python digits needed, = ceiling(n/SHIFT). */ n = (n + SHIFT - 1) / SHIFT; --- 1127,1139 ---- if (k < 0 || k >= base) break; ++p; } *str = p; + n = (p - start) * bits_per_char; + if (n / bits_per_char != p - start) { + PyErr_SetString(PyExc_ValueError, + "long string too large to convert"); + return NULL; + } /* n <- # of Python digits needed, = ceiling(n/SHIFT). */ n = (n + SHIFT - 1) / SHIFT; From nnorwitz@users.sourceforge.net Sun Feb 2 17:59:08 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 02 Feb 2003 09:59:08 -0800 Subject: [Python-checkins] python/dist/src setup.py,1.140,1.141 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv7239 Modified Files: setup.py Log Message: Get ossaudiodev to compile on freebsd 4.7 Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.140 retrieving revision 1.141 diff -C2 -d -r1.140 -r1.141 *** setup.py 1 Feb 2003 00:10:09 -0000 1.140 --- setup.py 2 Feb 2003 17:59:05 -0000 1.141 *************** *** 743,748 **** exts.append( Extension('linuxaudiodev', ['linuxaudiodev.c']) ) # ossaudiodev currently doesn't work, so don't build. ! ## # XXX should also build this on FreeBSD! ## exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) ) --- 743,749 ---- exts.append( Extension('linuxaudiodev', ['linuxaudiodev.c']) ) + if platform in ('linux2', 'freebsd4'): # ossaudiodev currently doesn't work, so don't build. ! pass ## exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) ) From nnorwitz@users.sourceforge.net Sun Feb 2 17:59:08 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 02 Feb 2003 09:59:08 -0800 Subject: [Python-checkins] python/dist/src/Modules ossaudiodev.c,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv7239/Modules Modified Files: ossaudiodev.c Log Message: Get ossaudiodev to compile on freebsd 4.7 Index: ossaudiodev.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/ossaudiodev.c,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** ossaudiodev.c 10 Jan 2003 21:27:54 -0000 1.21 --- ossaudiodev.c 2 Feb 2003 17:59:06 -0000 1.22 *************** *** 77,81 **** --- 77,83 ---- { 16, AFMT_S16_BE, "linear signed 16-bit big-endian audio" }, { 16, AFMT_S16_LE, "linear signed 16-bit little-endian audio" }, + #ifdef AFMT_S16_NE { 16, AFMT_S16_NE, "linear signed 16-bit native-endian audio" }, + #endif }; *************** *** 964,968 **** --- 966,972 ---- _EXPORT_INT(m, AFMT_MPEG); _EXPORT_INT(m, AFMT_AC3); + #ifdef AFMT_S16_NE _EXPORT_INT(m, AFMT_S16_NE); + #endif /* Expose the sound mixer device numbers. */ *************** *** 1006,1014 **** --- 1010,1022 ---- _EXPORT_INT(m, SNDCTL_COPR_WCODE); _EXPORT_INT(m, SNDCTL_COPR_WDATA); + #ifdef SNDCTL_DSP_BIND_CHANNEL _EXPORT_INT(m, SNDCTL_DSP_BIND_CHANNEL); + #endif _EXPORT_INT(m, SNDCTL_DSP_CHANNELS); _EXPORT_INT(m, SNDCTL_DSP_GETBLKSIZE); _EXPORT_INT(m, SNDCTL_DSP_GETCAPS); + #ifdef SNDCTL_DSP_GETCHANNELMASK _EXPORT_INT(m, SNDCTL_DSP_GETCHANNELMASK); + #endif _EXPORT_INT(m, SNDCTL_DSP_GETFMTS); _EXPORT_INT(m, SNDCTL_DSP_GETIPTR); *************** *** 1025,1029 **** --- 1033,1039 ---- _EXPORT_INT(m, SNDCTL_DSP_NONBLOCK); _EXPORT_INT(m, SNDCTL_DSP_POST); + #ifdef SNDCTL_DSP_PROFILE _EXPORT_INT(m, SNDCTL_DSP_PROFILE); + #endif _EXPORT_INT(m, SNDCTL_DSP_RESET); _EXPORT_INT(m, SNDCTL_DSP_SAMPLESIZE); *************** *** 1049,1053 **** --- 1059,1065 ---- _EXPORT_INT(m, SNDCTL_SEQ_GETINCOUNT); _EXPORT_INT(m, SNDCTL_SEQ_GETOUTCOUNT); + #ifdef SNDCTL_SEQ_GETTIME _EXPORT_INT(m, SNDCTL_SEQ_GETTIME); + #endif _EXPORT_INT(m, SNDCTL_SEQ_NRMIDIS); _EXPORT_INT(m, SNDCTL_SEQ_NRSYNTHS); *************** *** 1060,1068 **** --- 1072,1086 ---- _EXPORT_INT(m, SNDCTL_SEQ_TESTMIDI); _EXPORT_INT(m, SNDCTL_SEQ_THRESHOLD); + #ifdef SNDCTL_SYNTH_CONTROL _EXPORT_INT(m, SNDCTL_SYNTH_CONTROL); + #endif + #ifdef SNDCTL_SYNTH_ID _EXPORT_INT(m, SNDCTL_SYNTH_ID); + #endif _EXPORT_INT(m, SNDCTL_SYNTH_INFO); _EXPORT_INT(m, SNDCTL_SYNTH_MEMAVL); + #ifdef SNDCTL_SYNTH_REMOVESAMPLE _EXPORT_INT(m, SNDCTL_SYNTH_REMOVESAMPLE); + #endif _EXPORT_INT(m, SNDCTL_TMR_CONTINUE); _EXPORT_INT(m, SNDCTL_TMR_METRONOME); From tim_one@users.sourceforge.net Sun Feb 2 17:59:13 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 02 Feb 2003 09:59:13 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv7126/Lib/test Modified Files: pickletester.py Log Message: Implemented proto 2 NEWTRUE and NEWFALSE in cPickle. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** pickletester.py 2 Feb 2003 17:26:39 -0000 1.35 --- pickletester.py 2 Feb 2003 17:59:11 -0000 1.36 *************** *** 503,506 **** --- 503,512 ---- self.assert_(x is y, (proto, x, s, y)) + # Test that proto >= 2 really uses the bool opcodes. + if proto >= 2 and x in (False, True): + expected = x and pickle.NEWTRUE or pickle.NEWFALSE + # Skip the PROTO opcode at the start. + self.assertEqual(s[2], expected) + def test_newobj_tuple(self): x = MyTuple([1, 2, 3]) From tim_one@users.sourceforge.net Sun Feb 2 17:59:13 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 02 Feb 2003 09:59:13 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.112,2.113 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv7126/Modules Modified Files: cPickle.c Log Message: Implemented proto 2 NEWTRUE and NEWFALSE in cPickle. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.112 retrieving revision 2.113 diff -C2 -d -r2.112 -r2.113 *** cPickle.c 2 Feb 2003 17:26:40 -0000 2.112 --- cPickle.c 2 Feb 2003 17:59:11 -0000 2.113 *************** *** 964,970 **** long l = PyInt_AS_LONG((PyIntObject *)args); ! if ((*self->write_func)(self, buf[l], len[l]) < 0) return -1; - return 0; } --- 964,974 ---- long l = PyInt_AS_LONG((PyIntObject *)args); ! if (self->proto >= 2) { ! char opcode = l ? NEWTRUE : NEWFALSE; ! if (self->write_func(self, &opcode, 1) < 0) ! return -1; ! } ! else if (self->write_func(self, buf[l], len[l]) < 0) return -1; return 0; } *************** *** 2790,2793 **** --- 2794,2806 ---- } + static int + load_bool(Unpicklerobject *self, PyObject *boolean) + { + assert(boolean == Py_True || boolean == Py_False); + Py_INCREF(boolean); + PDATA_PUSH(self->stack, boolean, -1); + return 0; + } + /* s contains x bytes of a little-endian integer. Return its value as a * C int. Obscure: when x is 1 or 2, this is an unsigned little-endian *************** *** 4145,4148 **** --- 4158,4171 ---- continue; + case NEWTRUE: + if (load_bool(self, Py_True) < 0) + break; + continue; + + case NEWFALSE: + if (load_bool(self, Py_False) < 0) + break; + continue; + case '\0': /* end of file */ *************** *** 4463,4466 **** --- 4486,4498 ---- continue; + case NEWTRUE: + if (load_bool(self, Py_True) < 0) + break; + continue; + + case NEWFALSE: + if (load_bool(self, Py_False) < 0) + break; + continue; default: cPickle_ErrFormat(UnpicklingError, From tim_one@users.sourceforge.net Sun Feb 2 18:08:36 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 02 Feb 2003 10:08:36 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.113,2.114 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv10761/Modules Modified Files: cPickle.c Log Message: Minor cleanup, mostly adding horizontal whitespace, and breaking apart embedded assignments, for readability. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.113 retrieving revision 2.114 diff -C2 -d -r2.113 -r2.114 *** cPickle.c 2 Feb 2003 17:59:11 -0000 2.113 --- cPickle.c 2 Feb 2003 18:08:34 -0000 2.114 *************** *** 2281,2313 **** /* set up an array to hold get/put status */ ! if ((lm=PyDict_Size(self->memo)) < 0) return NULL; lm++; ! if (! (have_get=malloc((lm)*sizeof(char)))) return PyErr_NoMemory(); ! memset(have_get,0,lm); /* Scan for gets. */ ! for (rsize=0, i=l; --i >= 0; ) { ! k=data->data[i]; ! if (PyString_Check(k)) { rsize += PyString_GET_SIZE(k); - } else if (PyInt_Check(k)) { /* put */ ! ik=PyInt_AS_LONG((PyIntObject*)k); ! if (ik >= lm || ik==0) { PyErr_SetString(PicklingError, "Invalid get data"); return NULL; } ! if (have_get[ik]) { /* with matching get */ ! if (ik < 256) rsize += 2; ! else rsize+=5; ! } } else if (! (PyTuple_Check(k) && PyTuple_GET_SIZE(k) == 2 && ! PyInt_Check((k=PyTuple_GET_ITEM(k,0)))) ) { PyErr_SetString(PicklingError, --- 2281,2312 ---- /* set up an array to hold get/put status */ ! lm = PyDict_Size(self->memo); ! if (lm < 0) return NULL; lm++; ! have_get = malloc(lm); ! if (have_get == NULL) return PyErr_NoMemory(); ! memset(have_get, 0, lm); /* Scan for gets. */ ! for (rsize = 0, i = l; --i >= 0; ) { ! k = data->data[i]; ! if (PyString_Check(k)) rsize += PyString_GET_SIZE(k); else if (PyInt_Check(k)) { /* put */ ! ik = PyInt_AS_LONG((PyIntObject*)k); ! if (ik >= lm || ik == 0) { PyErr_SetString(PicklingError, "Invalid get data"); return NULL; } ! if (have_get[ik]) /* with matching get */ ! rsize += ik < 256 ? 2 : 5; } else if (! (PyTuple_Check(k) && PyTuple_GET_SIZE(k) == 2 && ! PyInt_Check((k = PyTuple_GET_ITEM(k, 0)))) ) { PyErr_SetString(PicklingError, *************** *** 2317,2350 **** else { /* put */ ! ik=PyInt_AS_LONG((PyIntObject*)k); ! if (ik >= lm || ik==0) { PyErr_SetString(PicklingError, "Invalid get data"); return NULL; } ! have_get[ik]=1; ! if (ik < 256) rsize += 2; ! else rsize+=5; } - } /* Now generate the result */ ! if (!( r=PyString_FromStringAndSize(NULL,rsize))) goto err; ! s=PyString_AS_STRING((PyStringObject*)r); ! for (i=0; idata[i]; if (PyString_Check(k)) { ! ssize=PyString_GET_SIZE(k); if (ssize) { ! p=PyString_AS_STRING((PyStringObject*)k); ! while (--ssize >= 0) *s++=*p++; } } else if (PyTuple_Check(k)) { /* get */ ! ik=PyInt_AS_LONG((PyIntObject*)PyTuple_GET_ITEM(k,0)); if (ik < 256) { *s++ = BINGET; --- 2316,2350 ---- else { /* put */ ! ik = PyInt_AS_LONG((PyIntObject *)k); ! if (ik >= lm || ik == 0) { PyErr_SetString(PicklingError, "Invalid get data"); return NULL; } ! have_get[ik] = 1; ! rsize += ik < 256 ? 2 : 5; } } /* Now generate the result */ ! r = PyString_FromStringAndSize(NULL, rsize); ! if (r == NULL) goto err; ! s = PyString_AS_STRING((PyStringObject *)r); ! for (i = 0; i < l; i++) { ! k = data->data[i]; if (PyString_Check(k)) { ! ssize = PyString_GET_SIZE(k); if (ssize) { ! p=PyString_AS_STRING((PyStringObject *)k); ! while (--ssize >= 0) ! *s++ = *p++; } } else if (PyTuple_Check(k)) { /* get */ ! ik = PyInt_AS_LONG((PyIntObject *) ! PyTuple_GET_ITEM(k, 0)); if (ik < 256) { *s++ = BINGET; *************** *** 2361,2365 **** else { /* put */ ! ik=PyInt_AS_LONG((PyIntObject*)k); if (have_get[ik]) { /* with matching get */ --- 2361,2365 ---- else { /* put */ ! ik = PyInt_AS_LONG((PyIntObject*)k); if (have_get[ik]) { /* with matching get */ *************** *** 2377,2386 **** } } - } if (clear) { PyDict_Clear(self->memo); ! Pdata_clear(data,0); } --- 2377,2385 ---- } } } if (clear) { PyDict_Clear(self->memo); ! Pdata_clear(data, 0); } From tim_one@users.sourceforge.net Sun Feb 2 18:29:35 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 02 Feb 2003 10:29:35 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.114,2.115 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv16785/Modules Modified Files: cPickle.c Log Message: Massive edits. If p is a pointer to a struct, and p->f is a pointer to a function, then p->f(arg1, arg2, ...) is semantically the same as (*p->f)(arg1, arg2, ...) Changed all instances of the latter into the former. Given how often the code embeds this kind of expression in an if test, the unnecessary parens and dereferening operator were a real drag on readability. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.114 retrieving revision 2.115 diff -C2 -d -r2.114 -r2.115 *** cPickle.c 2 Feb 2003 18:08:34 -0000 2.114 --- cPickle.c 2 Feb 2003 18:29:33 -0000 2.115 *************** *** 687,691 **** } ! if ((*self->write_func)(self, s, len) < 0) return -1; --- 687,691 ---- } ! if (self->write_func(self, s, len) < 0) return -1; *************** *** 771,775 **** } ! if ((*self->write_func)(self, c_str, len) < 0) goto finally; --- 771,775 ---- } ! if (self->write_func(self, c_str, len) < 0) goto finally; *************** *** 951,955 **** { static char none = NONE; ! if ((*self->write_func)(self, &none, 1) < 0) return -1; --- 951,955 ---- { static char none = NONE; ! if (self->write_func(self, &none, 1) < 0) return -1; *************** *** 992,996 **** c_str[0] = INT; PyOS_snprintf(c_str + 1, sizeof(c_str) - 1, "%ld\n", l); ! if ((*self->write_func)(self, c_str, strlen(c_str)) < 0) return -1; } --- 992,996 ---- c_str[0] = INT; PyOS_snprintf(c_str + 1, sizeof(c_str) - 1, "%ld\n", l); ! if (self->write_func(self, c_str, strlen(c_str)) < 0) return -1; } *************** *** 1017,1021 **** } ! if ((*self->write_func)(self, c_str, len) < 0) return -1; } --- 1017,1021 ---- } ! if (self->write_func(self, c_str, len) < 0) return -1; } *************** *** 1121,1133 **** goto finally; ! if ((*self->write_func)(self, &l, 1) < 0) goto finally; ! if ((*self->write_func)(self, ! PyString_AS_STRING((PyStringObject *)repr), ! size) < 0) goto finally; ! if ((*self->write_func)(self, "\n", 1) < 0) goto finally; --- 1121,1133 ---- goto finally; ! if (self->write_func(self, &l, 1) < 0) goto finally; ! if (self->write_func(self, ! PyString_AS_STRING((PyStringObject *)repr), ! size) < 0) goto finally; ! if (self->write_func(self, "\n", 1) < 0) goto finally; *************** *** 1233,1237 **** *p = (unsigned char) (flo & 0xFF); ! if ((*self->write_func)(self, str, 9) < 0) return -1; } --- 1233,1237 ---- *p = (unsigned char) (flo & 0xFF); ! if (self->write_func(self, str, 9) < 0) return -1; } *************** *** 1241,1245 **** PyOS_snprintf(c_str + 1, sizeof(c_str) - 1, "%.17g\n", x); ! if ((*self->write_func)(self, c_str, strlen(c_str)) < 0) return -1; } --- 1241,1245 ---- PyOS_snprintf(c_str + 1, sizeof(c_str) - 1, "%.17g\n", x); ! if (self->write_func(self, c_str, strlen(c_str)) < 0) return -1; } *************** *** 1270,1280 **** repr_str = PyString_AS_STRING((PyStringObject *)repr); ! if ((*self->write_func)(self, &string, 1) < 0) goto err; ! if ((*self->write_func)(self, repr_str, len) < 0) goto err; ! if ((*self->write_func)(self, "\n", 1) < 0) goto err; --- 1270,1280 ---- repr_str = PyString_AS_STRING((PyStringObject *)repr); ! if (self->write_func(self, &string, 1) < 0) goto err; ! if (self->write_func(self, repr_str, len) < 0) goto err; ! if (self->write_func(self, "\n", 1) < 0) goto err; *************** *** 1300,1304 **** } ! if ((*self->write_func)(self, c_str, len) < 0) return -1; --- 1300,1304 ---- } ! if (self->write_func(self, c_str, len) < 0) return -1; *************** *** 1308,1313 **** } else { ! if ((*self->write_func)(self, ! PyString_AS_STRING((PyStringObject *)args), size) < 0) return -1; } --- 1308,1315 ---- } else { ! if (self->write_func(self, ! PyString_AS_STRING( ! (PyStringObject *)args), ! size) < 0) return -1; } *************** *** 1388,1398 **** repr_str = PyString_AS_STRING((PyStringObject *)repr); ! if ((*self->write_func)(self, &string, 1) < 0) goto err; ! if ((*self->write_func)(self, repr_str, len) < 0) goto err; ! if ((*self->write_func)(self, "\n", 1) < 0) goto err; --- 1390,1400 ---- repr_str = PyString_AS_STRING((PyStringObject *)repr); ! if (self->write_func(self, &string, 1) < 0) goto err; ! if (self->write_func(self, repr_str, len) < 0) goto err; ! if (self->write_func(self, "\n", 1) < 0) goto err; *************** *** 1414,1418 **** len = 5; ! if ((*self->write_func)(self, c_str, len) < 0) goto err; --- 1416,1420 ---- len = 5; ! if (self->write_func(self, c_str, len) < 0) goto err; *************** *** 1423,1428 **** } else { ! if ((*self->write_func)(self, PyString_AS_STRING(repr), ! size) < 0) goto err; } --- 1425,1430 ---- } else { ! if (self->write_func(self, PyString_AS_STRING(repr), ! size) < 0) goto err; } *************** *** 1452,1456 **** static char tuple = TUPLE; ! if ((*self->write_func)(self, &MARKv, 1) < 0) goto finally; --- 1454,1458 ---- static char tuple = TUPLE; ! if (self->write_func(self, &MARKv, 1) < 0) goto finally; *************** *** 1474,1478 **** static char pop_mark = POP_MARK; ! if ((*self->write_func)(self, &pop_mark, 1) < 0) goto finally; } --- 1476,1480 ---- static char pop_mark = POP_MARK; ! if (self->write_func(self, &pop_mark, 1) < 0) goto finally; } *************** *** 1481,1485 **** for (i = 0; i <= len; i++) { ! if ((*self->write_func)(self, &pop, 1) < 0) goto finally; } --- 1483,1487 ---- for (i = 0; i <= len; i++) { ! if (self->write_func(self, &pop, 1) < 0) goto finally; } *************** *** 1494,1498 **** } ! if ((*self->write_func)(self, &tuple, 1) < 0) { goto finally; } --- 1496,1500 ---- } ! if (self->write_func(self, &tuple, 1) < 0) { goto finally; } *************** *** 1514,1518 **** static char tuple = EMPTY_TUPLE; ! return (*self->write_func)(self, &tuple, 1); } --- 1516,1520 ---- static char tuple = EMPTY_TUPLE; ! return self->write_func(self, &tuple, 1); } *************** *** 1543,1547 **** goto finally; ! if ((*self->write_func)(self, s, s_len) < 0) goto finally; --- 1545,1549 ---- goto finally; ! if (self->write_func(self, s, s_len) < 0) goto finally; *************** *** 1556,1560 **** if ((using_appends = (self->bin && (len > 1)))) ! if ((*self->write_func)(self, &MARKv, 1) < 0) goto finally; --- 1558,1562 ---- if ((using_appends = (self->bin && (len > 1)))) ! if (self->write_func(self, &MARKv, 1) < 0) goto finally; *************** *** 1567,1571 **** if (!using_appends) { ! if ((*self->write_func)(self, &append, 1) < 0) goto finally; } --- 1569,1573 ---- if (!using_appends) { ! if (self->write_func(self, &append, 1) < 0) goto finally; } *************** *** 1573,1577 **** if (using_appends) { ! if ((*self->write_func)(self, &appends, 1) < 0) goto finally; } --- 1575,1579 ---- if (using_appends) { ! if (self->write_func(self, &appends, 1) < 0) goto finally; } *************** *** 1609,1613 **** } ! if ((*self->write_func)(self, s, len) < 0) goto finally; --- 1611,1615 ---- } ! if (self->write_func(self, s, len) < 0) goto finally; *************** *** 1625,1629 **** if ((using_setitems = (self->bin && (PyDict_Size(args) > 1)))) ! if ((*self->write_func)(self, &MARKv, 1) < 0) goto finally; --- 1627,1631 ---- if ((using_setitems = (self->bin && (PyDict_Size(args) > 1)))) ! if (self->write_func(self, &MARKv, 1) < 0) goto finally; *************** *** 1637,1641 **** if (!using_setitems) { ! if ((*self->write_func)(self, &setitem, 1) < 0) goto finally; } --- 1639,1643 ---- if (!using_setitems) { ! if (self->write_func(self, &setitem, 1) < 0) goto finally; } *************** *** 1643,1647 **** if (using_setitems) { ! if ((*self->write_func)(self, &setitems, 1) < 0) goto finally; } --- 1645,1649 ---- if (using_setitems) { ! if (self->write_func(self, &setitems, 1) < 0) goto finally; } *************** *** 1670,1674 **** goto finally; ! if ((*self->write_func)(self, &MARKv, 1) < 0) goto finally; --- 1672,1676 ---- goto finally; ! if (self->write_func(self, &MARKv, 1) < 0) goto finally; *************** *** 1725,1744 **** name_str = PyString_AS_STRING((PyStringObject *)name); ! if ((*self->write_func)(self, &inst, 1) < 0) goto finally; ! if ((*self->write_func)(self, module_str, module_size) < 0) goto finally; ! if ((*self->write_func)(self, "\n", 1) < 0) goto finally; ! if ((*self->write_func)(self, name_str, name_size) < 0) goto finally; ! if ((*self->write_func)(self, "\n", 1) < 0) goto finally; } ! else if ((*self->write_func)(self, &obj, 1) < 0) { goto finally; } --- 1727,1746 ---- name_str = PyString_AS_STRING((PyStringObject *)name); ! if (self->write_func(self, &inst, 1) < 0) goto finally; ! if (self->write_func(self, module_str, module_size) < 0) goto finally; ! if (self->write_func(self, "\n", 1) < 0) goto finally; ! if (self->write_func(self, name_str, name_size) < 0) goto finally; ! if (self->write_func(self, "\n", 1) < 0) goto finally; } ! else if (self->write_func(self, &obj, 1) < 0) { goto finally; } *************** *** 1771,1775 **** goto finally; ! if ((*self->write_func)(self, &build, 1) < 0) goto finally; --- 1773,1777 ---- goto finally; ! if (self->write_func(self, &build, 1) < 0) goto finally; *************** *** 1844,1860 **** Py_DECREF(klass); ! if ((*self->write_func)(self, &global, 1) < 0) goto finally; ! if ((*self->write_func)(self, module_str, module_size) < 0) goto finally; ! if ((*self->write_func)(self, "\n", 1) < 0) goto finally; ! if ((*self->write_func)(self, name_str, name_size) < 0) goto finally; ! if ((*self->write_func)(self, "\n", 1) < 0) goto finally; --- 1846,1862 ---- Py_DECREF(klass); ! if (self->write_func(self, &global, 1) < 0) goto finally; ! if (self->write_func(self, module_str, module_size) < 0) goto finally; ! if (self->write_func(self, "\n", 1) < 0) goto finally; ! if (self->write_func(self, name_str, name_size) < 0) goto finally; ! if (self->write_func(self, "\n", 1) < 0) goto finally; *************** *** 1896,1900 **** } ! if ((*self->write_func)(self, &persid, 1) < 0) goto finally; --- 1898,1902 ---- } ! if (self->write_func(self, &persid, 1) < 0) goto finally; *************** *** 1902,1910 **** goto finally; ! if ((*self->write_func)(self, ! PyString_AS_STRING((PyStringObject *)pid), size) < 0) goto finally; ! if ((*self->write_func)(self, "\n", 1) < 0) goto finally; --- 1904,1914 ---- goto finally; ! if (self->write_func(self, ! PyString_AS_STRING( ! (PyStringObject *)pid), ! size) < 0) goto finally; ! if (self->write_func(self, "\n", 1) < 0) goto finally; *************** *** 1913,1917 **** } else if (save(self, pid, 1) >= 0) { ! if ((*self->write_func)(self, &binpersid, 1) < 0) res = -1; else --- 1917,1921 ---- } else if (save(self, pid, 1) >= 0) { ! if (self->write_func(self, &binpersid, 1) < 0) res = -1; else *************** *** 1943,1947 **** return -1; ! if ((*self->write_func)(self, &reduce, 1) < 0) return -1; --- 1947,1951 ---- return -1; ! if (self->write_func(self, &reduce, 1) < 0) return -1; *************** *** 1961,1965 **** return -1; ! if ((*self->write_func)(self, &build, 1) < 0) return -1; } --- 1965,1969 ---- return -1; ! if (self->write_func(self, &build, 1) < 0) return -1; } *************** *** 2756,2760 **** long l; ! if ((len = (*self->readline_func)(self, &s)) < 0) return -1; if (len < 2) return bad_readline(); if (!( s=pystrndup(s,len))) return -1; --- 2760,2764 ---- long l; ! if ((len = self->readline_func(self, &s)) < 0) return -1; if (len < 2) return bad_readline(); if (!( s=pystrndup(s,len))) return -1; *************** *** 2851,2855 **** char *s; ! if ((*self->read_func)(self, &s, 4) < 0) return -1; --- 2855,2859 ---- char *s; ! if (self->read_func(self, &s, 4) < 0) return -1; *************** *** 2863,2867 **** char *s; ! if ((*self->read_func)(self, &s, 1) < 0) return -1; --- 2867,2871 ---- char *s; ! if (self->read_func(self, &s, 1) < 0) return -1; *************** *** 2875,2879 **** char *s; ! if ((*self->read_func)(self, &s, 2) < 0) return -1; --- 2879,2883 ---- char *s; ! if (self->read_func(self, &s, 2) < 0) return -1; *************** *** 2888,2892 **** int len, res = -1; ! if ((len = (*self->readline_func)(self, &s)) < 0) return -1; if (len < 2) return bad_readline(); if (!( s=pystrndup(s,len))) return -1; --- 2892,2896 ---- int len, res = -1; ! if ((len = self->readline_func(self, &s)) < 0) return -1; if (len < 2) return bad_readline(); if (!( s=pystrndup(s,len))) return -1; *************** *** 2953,2957 **** double d; ! if ((len = (*self->readline_func)(self, &s)) < 0) return -1; if (len < 2) return bad_readline(); if (!( s=pystrndup(s,len))) return -1; --- 2957,2961 ---- double d; ! if ((len = self->readline_func(self, &s)) < 0) return -1; if (len < 2) return bad_readline(); if (!( s=pystrndup(s,len))) return -1; *************** *** 2988,2992 **** char *p; ! if ((*self->read_func)(self, &p, 8) < 0) return -1; --- 2992,2996 ---- char *p; ! if (self->read_func(self, &p, 8) < 0) return -1; *************** *** 3052,3056 **** char *s, *p; ! if ((len = (*self->readline_func)(self, &s)) < 0) return -1; if (len < 2) return bad_readline(); if (!( s=pystrndup(s,len))) return -1; --- 3056,3060 ---- char *s, *p; ! if ((len = self->readline_func(self, &s)) < 0) return -1; if (len < 2) return bad_readline(); if (!( s=pystrndup(s,len))) return -1; *************** *** 3094,3102 **** char *s; ! if ((*self->read_func)(self, &s, 4) < 0) return -1; l = calc_binint(s, 4); ! if ((*self->read_func)(self, &s, l) < 0) return -1; --- 3098,3106 ---- char *s; ! if (self->read_func(self, &s, 4) < 0) return -1; l = calc_binint(s, 4); ! if (self->read_func(self, &s, l) < 0) return -1; *************** *** 3116,3125 **** char *s; ! if ((*self->read_func)(self, &s, 1) < 0) return -1; l = (unsigned char)s[0]; ! if ((*self->read_func)(self, &s, l) < 0) return -1; if (!( py_string = PyString_FromStringAndSize(s, l))) return -1; --- 3120,3129 ---- char *s; ! if (self->read_func(self, &s, 1) < 0) return -1; l = (unsigned char)s[0]; ! if (self->read_func(self, &s, l) < 0) return -1; if (!( py_string = PyString_FromStringAndSize(s, l))) return -1; *************** *** 3138,3142 **** char *s; ! if ((len = (*self->readline_func)(self, &s)) < 0) return -1; if (len < 1) return bad_readline(); --- 3142,3146 ---- char *s; ! if ((len = self->readline_func(self, &s)) < 0) return -1; if (len < 1) return bad_readline(); *************** *** 3161,3169 **** char *s; ! if ((*self->read_func)(self, &s, 4) < 0) return -1; l = calc_binint(s, 4); ! if ((*self->read_func)(self, &s, l) < 0) return -1; --- 3165,3173 ---- char *s; ! if (self->read_func(self, &s, 4) < 0) return -1; l = calc_binint(s, 4); ! if (self->read_func(self, &s, l) < 0) return -1; *************** *** 3345,3354 **** if ((i = marker(self)) < 0) return -1; ! if ((len = (*self->readline_func)(self, &s)) < 0) return -1; if (len < 2) return bad_readline(); module_name = PyString_FromStringAndSize(s, len - 1); if (!module_name) return -1; ! if ((len = (*self->readline_func)(self, &s)) >= 0) { if (len < 2) return bad_readline(); if ((class_name = PyString_FromStringAndSize(s, len - 1))) { --- 3349,3358 ---- if ((i = marker(self)) < 0) return -1; ! if ((len = self->readline_func(self, &s)) < 0) return -1; if (len < 2) return bad_readline(); module_name = PyString_FromStringAndSize(s, len - 1); if (!module_name) return -1; ! if ((len = self->readline_func(self, &s)) >= 0) { if (len < 2) return bad_readline(); if ((class_name = PyString_FromStringAndSize(s, len - 1))) { *************** *** 3382,3391 **** char *s; ! if ((len = (*self->readline_func)(self, &s)) < 0) return -1; if (len < 2) return bad_readline(); module_name = PyString_FromStringAndSize(s, len - 1); if (!module_name) return -1; ! if ((len = (*self->readline_func)(self, &s)) >= 0) { if (len < 2) { Py_DECREF(module_name); --- 3386,3395 ---- char *s; ! if ((len = self->readline_func(self, &s)) < 0) return -1; if (len < 2) return bad_readline(); module_name = PyString_FromStringAndSize(s, len - 1); if (!module_name) return -1; ! if ((len = self->readline_func(self, &s)) >= 0) { if (len < 2) { Py_DECREF(module_name); *************** *** 3414,3418 **** if (self->pers_func) { ! if ((len = (*self->readline_func)(self, &s)) < 0) return -1; if (len < 2) return bad_readline(); --- 3418,3422 ---- if (self->pers_func) { ! if ((len = self->readline_func(self, &s)) < 0) return -1; if (len < 2) return bad_readline(); *************** *** 3547,3551 **** int rc; ! if ((len = (*self->readline_func)(self, &s)) < 0) return -1; if (len < 2) return bad_readline(); --- 3551,3555 ---- int rc; ! if ((len = self->readline_func(self, &s)) < 0) return -1; if (len < 2) return bad_readline(); *************** *** 3574,3578 **** int rc; ! if ((*self->read_func)(self, &s, 1) < 0) return -1; key = (unsigned char)s[0]; --- 3578,3582 ---- int rc; ! if (self->read_func(self, &s, 1) < 0) return -1; key = (unsigned char)s[0]; *************** *** 3602,3606 **** int rc; ! if ((*self->read_func)(self, &s, 4) < 0) return -1; c = (unsigned char)s[0]; --- 3606,3610 ---- int rc; ! if (self->read_func(self, &s, 4) < 0) return -1; c = (unsigned char)s[0]; *************** *** 3636,3640 **** char *s; ! if ((l = (*self->readline_func)(self, &s)) < 0) return -1; if (l < 2) return bad_readline(); if (!( len=self->stack->length )) return stackUnderflow(); --- 3640,3644 ---- char *s; ! if ((l = self->readline_func(self, &s)) < 0) return -1; if (l < 2) return bad_readline(); if (!( len=self->stack->length )) return stackUnderflow(); *************** *** 3655,3659 **** int len; ! if ((*self->read_func)(self, &s, 1) < 0) return -1; if (!( (len=self->stack->length) > 0 )) return stackUnderflow(); --- 3659,3663 ---- int len; ! if (self->read_func(self, &s, 1) < 0) return -1; if (!( (len=self->stack->length) > 0 )) return stackUnderflow(); *************** *** 3677,3681 **** int len; ! if ((*self->read_func)(self, &s, 4) < 0) return -1; if (!( len=self->stack->length )) return stackUnderflow(); --- 3681,3685 ---- int len; ! if (self->read_func(self, &s, 4) < 0) return -1; if (!( len=self->stack->length )) return stackUnderflow(); *************** *** 3933,3937 **** while (1) { ! if ((*self->read_func)(self, &s, 1) < 0) break; --- 3937,3941 ---- while (1) { ! if (self->read_func(self, &s, 1) < 0) break; *************** *** 4215,4220 **** if ((i = marker(self)) < 0) return -1; Pdata_clear(self->stack, i); ! if ((*self->readline_func)(self, &s) < 0) return -1; ! if ((*self->readline_func)(self, &s) < 0) return -1; PDATA_APPEND(self->stack, Py_None,-1); return 0; --- 4219,4224 ---- if ((i = marker(self)) < 0) return -1; Pdata_clear(self->stack, i); ! if (self->readline_func(self, &s) < 0) return -1; ! if (self->readline_func(self, &s) < 0) return -1; PDATA_APPEND(self->stack, Py_None,-1); return 0; *************** *** 4226,4231 **** char *s; ! if ((*self->readline_func)(self, &s) < 0) return -1; ! if ((*self->readline_func)(self, &s) < 0) return -1; PDATA_APPEND(self->stack, Py_None,-1); return 0; --- 4230,4235 ---- char *s; ! if (self->readline_func(self, &s) < 0) return -1; ! if (self->readline_func(self, &s) < 0) return -1; PDATA_APPEND(self->stack, Py_None,-1); return 0; *************** *** 4261,4265 **** while (1) { ! if ((*self->read_func)(self, &s, 1) < 0) break; --- 4265,4269 ---- while (1) { ! if (self->read_func(self, &s, 1) < 0) break; From jvr@users.sourceforge.net Sun Feb 2 18:56:40 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Sun, 02 Feb 2003 10:56:40 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac bundlebuilder.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv31923 Modified Files: bundlebuilder.py Log Message: jeez, now I know why I shouldn't even _want_ to learn sh. Index: bundlebuilder.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/bundlebuilder.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** bundlebuilder.py 1 Feb 2003 08:34:46 -0000 1.5 --- bundlebuilder.py 2 Feb 2003 18:56:37 -0000 1.6 *************** *** 255,265 **** #!/bin/sh ! execdir=$(dirname ${0}) executable=${execdir}/%(executable)s ! resdir=$(dirname ${execdir})/Resources main=${resdir}/%(mainprogram)s PYTHONPATH=$resdir export PYTHONPATH ! exec ${executable} ${main} ${1} """ --- 255,265 ---- #!/bin/sh ! execdir=$(dirname "${0}") executable=${execdir}/%(executable)s ! resdir=$(dirname "${execdir}")/Resources main=${resdir}/%(mainprogram)s PYTHONPATH=$resdir export PYTHONPATH ! exec "${executable}" "${main}" "${1}" """ *************** *** 620,624 **** --nib=NAME main nib name -c, --creator=CCCC 4-char creator code (default: '????') ! --iconfile=FILE filename of the icon (an .icns file) to be used as the Finder icon -l, --link symlink files/folder instead of copying them --- 620,624 ---- --nib=NAME main nib name -c, --creator=CCCC 4-char creator code (default: '????') ! --iconfile=FILE filename of the icon (an .icns file) to be used as the Finder icon -l, --link symlink files/folder instead of copying them From nnorwitz@users.sourceforge.net Sun Feb 2 19:06:12 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 02 Feb 2003 11:06:12 -0800 Subject: [Python-checkins] python/dist/src/Doc/api exceptions.tex,1.3.6.4,1.3.6.5 init.tex,1.2,1.2.10.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory sc8-pr-cvs1:/tmp/cvs-serv7057/api Modified Files: Tag: release22-maint exceptions.tex init.tex Log Message: Backport: date: 2002/12/06 22:42:13; author: theller; Typo: propogate -> propagate Index: exceptions.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/exceptions.tex,v retrieving revision 1.3.6.4 retrieving revision 1.3.6.5 diff -C2 -d -r1.3.6.4 -r1.3.6.5 *** exceptions.tex 24 Oct 2002 20:55:07 -0000 1.3.6.4 --- exceptions.tex 2 Feb 2003 19:06:03 -0000 1.3.6.5 *************** *** 20,24 **** error. If returning due to an error, it is important to indicate to the caller that an error has been set. If the error is not handled or ! carefully propogated, additional calls into the Python/C API may not behave as intended and may fail in mysterious ways. --- 20,24 ---- error. If returning due to an error, it is important to indicate to the caller that an error has been set. If the error is not handled or ! carefully propagated, additional calls into the Python/C API may not behave as intended and may fail in mysterious ways. Index: init.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/init.tex,v retrieving revision 1.2 retrieving revision 1.2.10.1 diff -C2 -d -r1.2 -r1.2.10.1 *** init.tex 16 Oct 2001 19:23:55 -0000 1.2 --- init.tex 2 Feb 2003 19:06:04 -0000 1.2.10.1 *************** *** 656,660 **** store state in the dictionary. If this function returns \NULL, an exception has been raised and the caller should allow it to ! propogate. \end{cfuncdesc} --- 656,660 ---- store state in the dictionary. If this function returns \NULL, an exception has been raised and the caller should allow it to ! propagate. \end{cfuncdesc} *************** *** 714,718 **** being executed. The effect of this is that as exception propogation causes the Python stack to unwind, the callback is called upon ! return to each frame as the exception propogates. Only trace functions receives these events; they are not needed by the profiler. --- 714,718 ---- being executed. The effect of this is that as exception propogation causes the Python stack to unwind, the callback is called upon ! return to each frame as the exception propagates. Only trace functions receives these events; they are not needed by the profiler. From nnorwitz@users.sourceforge.net Sun Feb 2 19:07:06 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 02 Feb 2003 11:07:06 -0800 Subject: [Python-checkins] python/dist/src/Doc/ext run-func.c,1.2.14.1,1.2.14.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ext In directory sc8-pr-cvs1:/tmp/cvs-serv7883/ext Modified Files: Tag: release22-maint run-func.c Log Message: backport: revision 1.4 date: 2002/12/17 00:40:38; author: nnorwitz; state: Exp; lines: +8 -3 Fix SF # 626275, missing DECREF's in embedding example Tested w/valgrind, all paths except the return on PyInt_AsLong() failure I think I got all of these right. Index: run-func.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ext/run-func.c,v retrieving revision 1.2.14.1 retrieving revision 1.2.14.2 diff -C2 -d -r1.2.14.1 -r1.2.14.2 *** run-func.c 2 Dec 2002 04:44:33 -0000 1.2.14.1 --- run-func.c 2 Feb 2003 19:07:01 -0000 1.2.14.2 *************** *** 18,21 **** --- 18,23 ---- pModule = PyImport_Import(pName); + Py_DECREF(pName); + if (pModule != NULL) { pDict = PyModule_GetDict(pModule); *************** *** 30,33 **** --- 32,37 ---- pValue = PyInt_FromLong(atoi(argv[i + 3])); if (!pValue) { + Py_DECREF(pArgs); + Py_DECREF(pModule); fprintf(stderr, "Cannot convert argument\n"); return 1; *************** *** 37,40 **** --- 41,45 ---- } pValue = PyObject_CallObject(pFunc, pArgs); + Py_DECREF(pArgs); if (pValue != NULL) { printf("Result of call: %ld\n", PyInt_AsLong(pValue)); *************** *** 42,54 **** } else { PyErr_Print(); fprintf(stderr,"Call failed\n"); return 1; } - Py_DECREF(pArgs); /* pDict and pFunc are borrowed and must not be Py_DECREF-ed */ } else { ! PyErr_Print(); fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]); } --- 47,60 ---- } else { + 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]); } *************** *** 60,64 **** return 1; } - Py_DECREF(pName); Py_Finalize(); return 0; --- 66,69 ---- From nnorwitz@users.sourceforge.net Sun Feb 2 19:09:07 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 02 Feb 2003 11:09:07 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libfuncs.tex,1.100.4.14,1.100.4.15 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv9298/lib Modified Files: Tag: release22-maint libfuncs.tex Log Message: backports: revision 1.127 date: 2003/01/04 02:16:22; author: rhettinger; state: Exp; lines: +1 -1 SF bug #655271: Slightly modify locals() doc Clarify the operation of locals(). revision 1.125 date: 2002/12/17 01:08:06; author: nnorwitz; state: Exp; lines: +6 -1 Fix SF # 641111, Undocumented side effect of eval Try to clear up confusion about the current globals being copied into a globals dict passed to eval(). This wording (more or less) was suggested in bug report. It should probably be made clearer. revision 1.124 date: 2002/12/17 01:02:57; author: nnorwitz; state: Exp; lines: +78 -0 Fix SF #642742, property() builtin not documented Added doc for functions new to 2.2: classmethod property staticmethod super Taken from docstrings. Could use review. Hope there wasn't a reason why these shouldn't have been added. Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.100.4.14 retrieving revision 1.100.4.15 diff -C2 -d -r1.100.4.14 -r1.100.4.15 *** libfuncs.tex 2 Jan 2003 04:54:22 -0000 1.100.4.14 --- libfuncs.tex 2 Feb 2003 19:08:58 -0000 1.100.4.15 *************** *** 83,86 **** --- 83,97 ---- \end{funcdesc} + \begin{funcdesc}{bool}{x} + Convert a value to a Boolean, using the standard truth testing + procedure. If \code{x} is false, this returns \code{False}; + otherwise it returns \code{True}. \code{bool} is also a class, + which is a subclass of \code{int}. Class \code{bool} cannot be + subclassed further. Its only instances are \code{False} and + \code{True}. + \indexii{Boolean}{type} + \versionadded{2.2.1} + \end{funcdesc} + \begin{funcdesc}{buffer}{object\optional{, offset\optional{, size}}} The \var{object} argument must be an object that supports the buffer *************** *** 110,113 **** --- 121,147 ---- \end{funcdesc} + \begin{funcdesc}{classmethod}{function} + Return a class method for \var{function}. + + A class method receives the class as implicit first argument, + just like an instance method receives the instance. + To declare a class method, use this idiom: + + \begin{verbatim} + class C: + def f(cls, arg1, arg2, ...): ... + f = classmethod(f) + \end{verbatim} + + It can be called either on the class (e.g. C.f()) or on an instance + (e.g. C().f()). The instance is ignored except for its class. + If a class method is called for a derived class, the derived class + object is passed as the implied first argument. + + Class methods are different than C++ or Java static methods. + If you want those, see \ref{staticmethod}. + \versionadded{2.2} + \end{funcdesc} + \begin{funcdesc}{cmp}{x, y} Compare the two objects \var{x} and \var{y} and return an integer *************** *** 265,269 **** expression (technically speaking, a condition list) using the \var{globals} and \var{locals} dictionaries as global and local name ! space. If the \var{locals} dictionary is omitted it defaults to the \var{globals} dictionary. If both dictionaries are omitted, the expression is executed in the environment where \keyword{eval} is --- 299,308 ---- expression (technically speaking, a condition list) using the \var{globals} and \var{locals} dictionaries as global and local name ! space. If the \var{globals} dictionary is present and lacks ! '__builtins__', the current globals are copied into \var{globals} before ! \var{expression} is parsed. This means that \var{expression} ! normally has full access to the standard ! \refmodule[builtin]{__builtin__} module and restricted environments ! are propagated. If the \var{locals} dictionary is omitted it defaults to the \var{globals} dictionary. If both dictionaries are omitted, the expression is executed in the environment where \keyword{eval} is *************** *** 546,550 **** \begin{funcdesc}{locals}{} ! Return a dictionary representing the current local symbol table. \warning{The contents of this dictionary should not be modified; changes may not affect the values of local variables used by the --- 585,589 ---- \begin{funcdesc}{locals}{} ! Update and return a dictionary representing the current local symbol table. \warning{The contents of this dictionary should not be modified; changes may not affect the values of local variables used by the *************** *** 633,636 **** --- 672,694 ---- \end{funcdesc} + \begin{funcdesc}{property}{\optional{fget\optional{, fset\optional{, fdel\optional{, doc}}}}} + Return a property attribute for new-style classes (classes that + derive from \function{object}. + + \var{fget} is a function for getting an attribute value, likewise + \var{fset} is a function for setting, and \var{fdel} a function + for del'ing, an attribute. Typical use is to define a managed attribute x: + + \begin{verbatim} + class C(object): + def getx(self): return self.__x + def setx(self, value): self.__x = value + def delx(self): del self.__x + x = property(getx, setx, delx, "I'm the 'x' property.") + \end{verbatim} + + \versionadded{2.2} + \end{funcdesc} + \begin{funcdesc}{range}{\optional{start,} stop\optional{, step}} This is a versatile function to create lists containing arithmetic *************** *** 778,781 **** --- 836,874 ---- indexing syntax is used. For example: \samp{a[start:stop:step]} or \samp{a[start:stop, i]}. + \end{funcdesc} + + \begin{funcdesc}{staticmethod}{function} + Return a static method for \var{function}. + + A static method does not receive an implicit first argument. + To declare a static method, use this idiom: + + \begin{verbatim} + class C: + def f(arg1, arg2, ...): ... + f = staticmethod(f) + \end{verbatim} + + It can be called either on the class (e.g. C.f()) or on an instance + (e.g. C().f()). The instance is ignored except for its class. + + Static methods in Python are similar to those found in Java or C++. + For a more advanced concept, see \ref{classmethod}. + \versionadded{2.2} + \end{funcdesc} + + \begin{funcdesc}{super}{type\optional{object-or-type}} + Return the superclass of \var{type}. If the second argument is omitted + the super object returned is unbound. If the second argument is an + object, isinstance(obj, type) must be true. If the second argument is a + type, issubclass(type2, type) must be true. + + A typical use for calling a cooperative superclass method is: + \begin{verbatim} + class C(B): + def meth(self, arg): + super(C, self).meth(arg) + \end{verbatim} + \versionadded{2.2} \end{funcdesc} From nnorwitz@users.sourceforge.net Sun Feb 2 19:23:18 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 02 Feb 2003 11:23:18 -0800 Subject: [Python-checkins] python/dist/src/Lib macpath.py,1.31.10.2,1.31.10.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv18473/Lib Modified Files: Tag: release22-maint macpath.py Log Message: Backport: revision 1.44 date: 2003/01/15 22:45:48; author: jackjansen; state: Exp; lines: +5 -0 Added ismount(). Fixes #661762, bugfix candidate. Index: macpath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/macpath.py,v retrieving revision 1.31.10.2 retrieving revision 1.31.10.3 diff -C2 -d -r1.31.10.2 -r1.31.10.3 *** macpath.py 13 Jan 2003 19:29:35 -0000 1.31.10.2 --- macpath.py 2 Feb 2003 19:23:13 -0000 1.31.10.3 *************** *** 94,97 **** --- 94,102 ---- def basename(s): return split(s)[1] + def ismount(s): + if not isabs(s): + return False + components = split(s) + return len(components) == 2 and components[1] == '' def isdir(s): From nnorwitz@users.sourceforge.net Sun Feb 2 19:24:41 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 02 Feb 2003 11:24:41 -0800 Subject: [Python-checkins] python/dist/src/Lib threading.py,1.19.12.2,1.19.12.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv19291/Lib Modified Files: Tag: release22-maint threading.py Log Message: backport: revision 1.29 date: 2002/11/21 21:08:39; author: gvanrossum; state: Exp; lines: +14 -8 The _Event class should be more careful with releasing its lock when interrupted. A try/finally will do nicely. Maybe other classes need this too, but since they manipulate more state it's less clear that that is always the right thing, and I'm in a hurry. Index: threading.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/threading.py,v retrieving revision 1.19.12.2 retrieving revision 1.19.12.3 diff -C2 -d -r1.19.12.2 -r1.19.12.3 *** threading.py 19 Feb 2002 03:02:33 -0000 1.19.12.2 --- threading.py 2 Feb 2003 19:24:38 -0000 1.19.12.3 *************** *** 317,334 **** def set(self): self.__cond.acquire() ! self.__flag = 1 ! self.__cond.notifyAll() ! self.__cond.release() def clear(self): self.__cond.acquire() ! self.__flag = 0 ! self.__cond.release() def wait(self, timeout=None): self.__cond.acquire() ! if not self.__flag: ! self.__cond.wait(timeout) ! self.__cond.release() # Helper to generate new thread names --- 317,340 ---- def set(self): self.__cond.acquire() ! try: ! self.__flag = 1 ! self.__cond.notifyAll() ! finally: ! self.__cond.release() def clear(self): self.__cond.acquire() ! try: ! self.__flag = 0 ! finally: ! self.__cond.release() def wait(self, timeout=None): self.__cond.acquire() ! try: ! if not self.__flag: ! self.__cond.wait(timeout) ! finally: ! self.__cond.release() # Helper to generate new thread names From nnorwitz@users.sourceforge.net Sun Feb 2 19:25:26 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 02 Feb 2003 11:25:26 -0800 Subject: [Python-checkins] python/dist/src/Objects structseq.c,1.3.6.3,1.3.6.4 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv19851/Objects Modified Files: Tag: release22-maint structseq.c Log Message: backport: revision 1.11 date: 2002/12/18 23:20:39; author: nnorwitz; state: Exp; lines: +6 -2 SF # 654974, fix unchecked return values in structseq Check return values after memory allocation. Index: structseq.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/structseq.c,v retrieving revision 1.3.6.3 retrieving revision 1.3.6.4 diff -C2 -d -r1.3.6.3 -r1.3.6.4 *** structseq.c 7 Mar 2002 15:16:07 -0000 1.3.6.3 --- structseq.c 2 Feb 2003 19:25:22 -0000 1.3.6.4 *************** *** 141,144 **** --- 141,147 ---- res = (PyStructSequence*) PyStructSequence_New(type); + if (res == NULL) { + return NULL; + } for (i = 0; i < len; ++i) { PyObject *v = PySequence_Fast_GET_ITEM(arg, i); *************** *** 347,350 **** --- 350,355 ---- members = PyMem_NEW(PyMemberDef, n_members+1); + if (members == NULL) + return; for (i = 0; i < n_members; ++i) { From nnorwitz@users.sourceforge.net Sun Feb 2 19:26:28 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 02 Feb 2003 11:26:28 -0800 Subject: [Python-checkins] python/dist/src/PC _winreg.c,1.8,1.8.26.1 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory sc8-pr-cvs1:/tmp/cvs-serv20494/PC Modified Files: Tag: release22-maint _winreg.c Log Message: backport: revision 1.14 date: 2003/01/15 23:38:15; author: mhammond; state: Exp; lines: +1 -1 Correct docstring for SetValueEx() revision 1.13 date: 2002/12/20 20:13:35; author: theller; state: Exp; lines: +1 -1 Fix an error message in the _winreg module. The error message referred to a constant in the 'win32con' module, but this constant is also defined in the _winreg module itself. Index: _winreg.c =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/_winreg.c,v retrieving revision 1.8 retrieving revision 1.8.26.1 diff -C2 -d -r1.8 -r1.8.26.1 *** _winreg.c 28 Jul 2000 03:44:41 -0000 1.8 --- _winreg.c 2 Feb 2003 19:26:25 -0000 1.8.26.1 *************** *** 260,264 **** "\n" "key is an already open key, or any one of the predefined HKEY_* constants.\n" ! "sub_key is a string that names the subkey with which the value is associated.\n" "type is an integer that specifies the type of the data. This should be one of:\n" " REG_BINARY -- Binary data in any form.\n" --- 260,264 ---- "\n" "key is an already open key, or any one of the predefined HKEY_* constants.\n" ! "value_name is a string containing the name of the value to set, or None\n" "type is an integer that specifies the type of the data. This should be one of:\n" " REG_BINARY -- Binary data in any form.\n" *************** *** 1317,1321 **** if (typ != REG_SZ) { PyErr_SetString(PyExc_TypeError, ! "Type must be win32con.REG_SZ"); return NULL; } --- 1317,1321 ---- if (typ != REG_SZ) { PyErr_SetString(PyExc_TypeError, ! "Type must be _winreg.REG_SZ"); return NULL; } From nnorwitz@users.sourceforge.net Sun Feb 2 19:34:21 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 02 Feb 2003 11:34:21 -0800 Subject: [Python-checkins] python/dist/src/Modules parsermodule.c,2.68,2.68.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv27568/Modules Modified Files: Tag: release22-maint parsermodule.c Log Message: backport: revision 2.75 date: 2003/01/29 14:20:22; author: mwh; state: Exp; lines: +2 -0 Teach the parsermodule about floor division. Fixes [ 676521 ] parser module validation failure Index: parsermodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/parsermodule.c,v retrieving revision 2.68 retrieving revision 2.68.6.1 diff -C2 -d -r2.68 -r2.68.6.1 *** parsermodule.c 8 Dec 2001 18:02:57 -0000 2.68 --- parsermodule.c 2 Feb 2003 19:34:14 -0000 2.68.6.1 *************** *** 1439,1442 **** --- 1439,1443 ---- || strcmp(s, "*=") == 0 || strcmp(s, "/=") == 0 + || strcmp(s, "//=") == 0 || strcmp(s, "%=") == 0 || strcmp(s, "&=") == 0 *************** *** 2094,2097 **** --- 2095,2099 ---- res = (((TYPE(CHILD(tree, pos)) == STAR) || (TYPE(CHILD(tree, pos)) == SLASH) + || (TYPE(CHILD(tree, pos)) == DOUBLESLASH) || (TYPE(CHILD(tree, pos)) == PERCENT)) && validate_factor(CHILD(tree, pos + 1))); From nnorwitz@users.sourceforge.net Sun Feb 2 19:34:43 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 02 Feb 2003 11:34:43 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_parser.py,1.10,1.10.12.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv27870/Lib/test Modified Files: Tag: release22-maint test_parser.py Log Message: backport: revision 1.14 date: 2003/01/29 14:20:23; author: mwh; state: Exp; lines: +5 -0 Teach the parsermodule about floor division. Fixes [ 676521 ] parser module validation failure Index: test_parser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_parser.py,v retrieving revision 1.10 retrieving revision 1.10.12.1 diff -C2 -d -r1.10 -r1.10.12.1 *** test_parser.py 20 Sep 2001 21:33:42 -0000 1.10 --- test_parser.py 2 Feb 2003 19:34:40 -0000 1.10.12.1 *************** *** 55,58 **** --- 55,62 ---- self.check_expr("foo(a, b, c, **kw)") self.check_expr("foo + bar") + self.check_expr("foo - bar") + self.check_expr("foo * bar") + self.check_expr("foo / bar") + self.check_expr("foo // bar") self.check_expr("lambda: 0") self.check_expr("lambda x: 0") *************** *** 89,92 **** --- 93,97 ---- self.check_suite("a *= b") self.check_suite("a /= b") + self.check_suite("a //= b") self.check_suite("a %= b") self.check_suite("a &= b") From nnorwitz@users.sourceforge.net Sun Feb 2 19:37:53 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 02 Feb 2003 11:37:53 -0800 Subject: [Python-checkins] python/dist/src/Objects classobject.c,2.154.8.2,2.154.8.3 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv29591/Objects Modified Files: Tag: release22-maint classobject.c Log Message: backport: revision 2.164 date: 2002/10/29 18:36:40; author: gvanrossum; state: Exp; lines: +12 -13 Since properties are supported here, is possible that instance_getattr2() raises an exception. Fix all code that made this assumption. Index: classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.154.8.2 retrieving revision 2.154.8.3 diff -C2 -d -r2.154.8.2 -r2.154.8.3 *** classobject.c 18 Oct 2002 14:06:02 -0000 2.154.8.2 --- classobject.c 2 Feb 2003 19:37:32 -0000 2.154.8.3 *************** *** 544,547 **** --- 544,551 ---- init = instance_getattr2(inst, initstr); if (init == NULL) { + if (PyErr_Occurred()) { + Py_DECREF(inst); + return NULL; + } if ((arg != NULL && (!PyTuple_Check(arg) || PyTuple_Size(arg) != 0)) *************** *** 675,679 **** } v = instance_getattr2(inst, name); ! if (v == NULL) { PyErr_Format(PyExc_AttributeError, "%.50s instance has no attribute '%.400s'", --- 679,683 ---- } v = instance_getattr2(inst, name); ! if (v == NULL && !PyErr_Occurred()) { PyErr_Format(PyExc_AttributeError, "%.50s instance has no attribute '%.400s'", *************** *** 1760,1782 **** instance_getattr2 directly because it will not set an exception on failure. */ ! if (((PyInstanceObject *)v)->in_class->cl_getattr == NULL) { ! method = instance_getattr2((PyInstanceObject *)v, name_op[op]); ! if (method == NULL) { ! assert(!PyErr_Occurred()); ! res = Py_NotImplemented; ! Py_INCREF(res); ! return res; ! } ! } else { method = PyObject_GetAttr(v, name_op[op]); ! if (method == NULL) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return NULL; PyErr_Clear(); - res = Py_NotImplemented; - Py_INCREF(res); - return res; } } --- 1764,1781 ---- instance_getattr2 directly because it will not set an exception on failure. */ ! if (((PyInstanceObject *)v)->in_class->cl_getattr == NULL) ! method = instance_getattr2((PyInstanceObject *)v, name_op[op]); ! else method = PyObject_GetAttr(v, name_op[op]); ! if (method == NULL) { ! if (PyErr_Occurred()) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return NULL; PyErr_Clear(); } + res = Py_NotImplemented; + Py_INCREF(res); + return res; } From nnorwitz@users.sourceforge.net Sun Feb 2 19:38:22 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 02 Feb 2003 11:38:22 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_class.py,1.7.6.1,1.7.6.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv29958/Lib/test Modified Files: Tag: release22-maint test_class.py Log Message: backport: revision 1.10 date: 2002/10/29 19:08:29; author: gvanrossum; state: Exp; lines: +27 -0 Added test for this fix to classobject.c: Since properties are supported here, is possible that instance_getattr2() raises an exception. Fix all code that made this assumption. Index: test_class.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_class.py,v retrieving revision 1.7.6.1 retrieving revision 1.7.6.2 diff -C2 -d -r1.7.6.1 -r1.7.6.2 *** test_class.py 13 Jun 2002 21:36:35 -0000 1.7.6.1 --- test_class.py 2 Feb 2003 19:38:19 -0000 1.7.6.2 *************** *** 289,290 **** --- 289,317 ---- else: raise TestFailed, "how could this not have overflowed the stack?" + + + # Tests for exceptions raised in instance_getattr2(). + + def booh(self): + raise AttributeError, "booh" + + class A: + a = property(booh) + try: + A().a # Raised AttributeError: A instance has no attribute 'a' + except AttributeError, x: + if str(x) is not "booh": + print "attribute error for A().a got masked:", str(x) + + class E: + __eq__ = property(booh) + E() == E() # In debug mode, caused a C-level assert() to fail + + class I: + __init__ = property(booh) + try: + I() # In debug mode, printed XXX undetected error and raises AttributeError + except AttributeError, x: + pass + else: + print "attribute error for I.__init__ got masked" From nnorwitz@users.sourceforge.net Sun Feb 2 20:00:03 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 02 Feb 2003 12:00:03 -0800 Subject: [Python-checkins] python/dist/src/Objects typeobject.c,2.126.4.31,2.126.4.32 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv8324/Objects Modified Files: Tag: release22-maint typeobject.c Log Message: backport: revision 2.196 date: 2002/12/07 21:39:16; author: tim_one; state: Exp; lines: +27 -28 slot_nb_nonzero(): Another leak uncovered by the sandbox datetime tests. I found the logic too confusing to follow here, so rewrote more than was likely absolutely necessary. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.126.4.31 retrieving revision 2.126.4.32 diff -C2 -d -r2.126.4.31 -r2.126.4.32 *** typeobject.c 7 Jan 2003 21:47:44 -0000 2.126.4.31 --- typeobject.c 2 Feb 2003 19:59:59 -0000 2.126.4.32 *************** *** 3114,3119 **** slot_nb_nonzero(PyObject *self) { ! PyObject *func, *res; static PyObject *nonzero_str, *len_str; func = lookup_maybe(self, "__nonzero__", &nonzero_str); --- 3114,3120 ---- slot_nb_nonzero(PyObject *self) { ! PyObject *func, *args; static PyObject *nonzero_str, *len_str; + int result = -1; func = lookup_maybe(self, "__nonzero__", &nonzero_str); *************** *** 3122,3137 **** return -1; func = lookup_maybe(self, "__len__", &len_str); ! if (func == NULL) { ! if (PyErr_Occurred()) ! return -1; ! else ! return 1; } } - res = PyObject_CallObject(func, NULL); Py_DECREF(func); ! if (res == NULL) ! return -1; ! return PyObject_IsTrue(res); } --- 3123,3140 ---- return -1; func = lookup_maybe(self, "__len__", &len_str); ! if (func == NULL) ! return PyErr_Occurred() ? -1 : 1; ! } ! args = PyTuple_New(0); ! if (args != NULL) { ! PyObject *temp = PyObject_Call(func, args, NULL); ! Py_DECREF(args); ! if (temp != NULL) { ! result = PyObject_IsTrue(temp); ! Py_DECREF(temp); } } Py_DECREF(func); ! return result; } From tim_one@users.sourceforge.net Sun Feb 2 20:29:41 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 02 Feb 2003 12:29:41 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv28209/Lib/test Modified Files: pickletester.py Log Message: cPickle support for TUPLE[123]. Incidentally plugged several undetected overflow holes in Pdata_grow(). Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** pickletester.py 2 Feb 2003 17:59:11 -0000 1.36 --- pickletester.py 2 Feb 2003 20:29:38 -0000 1.37 *************** *** 485,488 **** --- 485,509 ---- def test_short_tuples(self): + # Map (proto, len(tuple)) to expected opcode. + expected_opcode = {(0, 0): pickle.TUPLE, + (0, 1): pickle.TUPLE, + (0, 2): pickle.TUPLE, + (0, 3): pickle.TUPLE, + (0, 4): pickle.TUPLE, + + (1, 0): pickle.EMPTY_TUPLE, + (1, 1): pickle.TUPLE, + (1, 2): pickle.TUPLE, + (1, 3): pickle.TUPLE, + (1, 4): pickle.TUPLE, + + (2, 0): pickle.EMPTY_TUPLE, + (2, 1): pickle.TUPLE1, + (2, 2): pickle.TUPLE2, + (2, 3): pickle.TUPLE3, + (2, 4): pickle.TUPLE, + } + all_tuple_opcodes = (pickle.TUPLE, pickle.EMPTY_TUPLE, + pickle.TUPLE1, pickle.TUPLE2, pickle.TUPLE3) a = () b = (1,) *************** *** 495,498 **** --- 516,529 ---- y = self.loads(s) self.assertEqual(x, y, (proto, x, s, y)) + + # Verify that the protocol-correct tuple-building opcode + # was generated. + expected = expected_opcode[proto, len(x)] + for opcode in s: + if opcode in all_tuple_opcodes: + self.assertEqual(expected, opcode) + break + else: + self.fail("didn't find a tuple-building opcode in pickle") def test_singletons(self): From tim_one@users.sourceforge.net Sun Feb 2 20:29:40 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 02 Feb 2003 12:29:40 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.139,1.140 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv28209/Lib Modified Files: pickle.py Log Message: cPickle support for TUPLE[123]. Incidentally plugged several undetected overflow holes in Pdata_grow(). Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.139 retrieving revision 1.140 diff -C2 -d -r1.139 -r1.140 *** pickle.py 2 Feb 2003 07:51:32 -0000 1.139 --- pickle.py 2 Feb 2003 20:29:38 -0000 1.140 *************** *** 622,627 **** n = len(obj) ! if n == 0 and proto: ! write(EMPTY_TUPLE) return --- 622,630 ---- n = len(obj) ! if n == 0: ! if proto: ! write(EMPTY_TUPLE) ! else: ! write(MARK + TUPLE) return *************** *** 640,644 **** return ! # proto 0, or proto 1 and tuple isn't empty, or proto > 1 and tuple # has more than 3 elements. write(MARK) --- 643,647 ---- return ! # proto 0 or proto 1 and tuple isn't empty, or proto > 1 and tuple # has more than 3 elements. write(MARK) *************** *** 646,650 **** save(element) ! if n and id(obj) in memo: # Subtle. d was not in memo when we entered save_tuple(), so # the process of saving the tuple's elements must have saved --- 649,653 ---- save(element) ! if id(obj) in memo: # Subtle. d was not in memo when we entered save_tuple(), so # the process of saving the tuple's elements must have saved *************** *** 661,668 **** return ! # No recursion (including the empty-tuple case for protocol 0). self.write(TUPLE) ! if obj: # No need to memoize empty tuple ! self.memoize(obj) dispatch[TupleType] = save_tuple --- 664,670 ---- return ! # No recursion. self.write(TUPLE) ! self.memoize(obj) dispatch[TupleType] = save_tuple From tim_one@users.sourceforge.net Sun Feb 2 20:29:41 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 02 Feb 2003 12:29:41 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.115,2.116 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv28209/Modules Modified Files: cPickle.c Log Message: cPickle support for TUPLE[123]. Incidentally plugged several undetected overflow holes in Pdata_grow(). Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.115 retrieving revision 2.116 diff -C2 -d -r2.115 -r2.116 *** cPickle.c 2 Feb 2003 18:29:33 -0000 2.115 --- cPickle.c 2 Feb 2003 20:29:39 -0000 2.116 *************** *** 111,115 **** typedef struct { PyObject_HEAD ! int length, size; PyObject **data; } Pdata; --- 111,116 ---- typedef struct { PyObject_HEAD ! int length; /* number of initial slots in data currently used */ ! int size; /* number of slots in data allocated */ PyObject **data; } Pdata; *************** *** 121,128 **** PyObject **p; ! for (i=self->length, p=self->data; --i >= 0; p++) Py_DECREF(*p); ! ! if (self->data) free(self->data); ! PyObject_Del(self); } --- 122,130 ---- PyObject **p; ! for (i = self->length, p = self->data; --i >= 0; p++) { ! Py_DECREF(*p); ! } ! if (self->data) ! free(self->data); PyObject_Del(self); } *************** *** 141,149 **** Pdata *self; ! if (!( self = PyObject_New(Pdata, &PdataType))) return NULL; ! self->size=8; ! self->length=0; ! self->data=malloc(self->size * sizeof(PyObject*)); ! if (self->data) return (PyObject*)self; Py_DECREF(self); return PyErr_NoMemory(); --- 143,153 ---- Pdata *self; ! if (!(self = PyObject_New(Pdata, &PdataType))) ! return NULL; ! self->size = 8; ! self->length = 0; ! self->data = malloc(self->size * sizeof(PyObject*)); ! if (self->data) ! return (PyObject*)self; Py_DECREF(self); return PyErr_NoMemory(); *************** *** 157,160 **** --- 161,167 ---- } + /* Retain only the initial clearto items. If clearto >= the current + * number of items, this is a (non-erroneous) NOP. + */ static int Pdata_clear(Pdata *self, int clearto) *************** *** 166,202 **** if (clearto >= self->length) return 0; ! for (i=self->length, p=self->data+clearto; --i >= clearto; p++) Py_DECREF(*p); ! self->length=clearto; return 0; } - static int Pdata_grow(Pdata *self) { ! if (! self->size) { ! PyErr_NoMemory(); ! return -1; ! } ! self->size *= 2; ! self->data = realloc(self->data, self->size*sizeof(PyObject*)); ! if (! self->data) { ! self->size = 0; ! PyErr_NoMemory(); ! return -1; ! } return 0; - } ! #define PDATA_POP(D,V) { \ ! if ((D)->length) V=D->data[--((D)->length)]; \ ! else { \ ! PyErr_SetString(UnpicklingError, "bad pickle data"); \ ! V=NULL; \ ! } \ } static PyObject * --- 173,226 ---- if (clearto >= self->length) return 0; ! for (i = self->length, p = self->data + clearto; ! --i >= clearto; ! p++) { Py_DECREF(*p); ! } ! self->length = clearto; return 0; } static int Pdata_grow(Pdata *self) { ! int bigger; ! size_t nbytes; ! ! if (! self->size) ! goto nomemory; ! bigger = self->size << 1; ! if (bigger <= 0) ! goto nomemory; ! if ((int)(size_t)bigger != bigger) ! goto nomemory; ! nbytes = (size_t)bigger * sizeof(PyObject *); ! if (nbytes / sizeof(PyObject *) != (size_t)bigger) ! goto nomemory; ! self->data = realloc(self->data, nbytes); ! if (self->data == NULL) ! goto nomemory; ! self->size = bigger; return 0; ! nomemory: ! self->size = 0; ! PyErr_NoMemory(); ! return -1; } + /* D is a Pdata *. Pop the topmost element and store it into V, which + * must be an lvalue holding PyObject *. On stack underflow, UnpicklingError + * is raised and V is set to NULL. D and V may be evaluated several times. + */ + #define PDATA_POP(D, V) { \ + if ((D)->length) \ + (V) = (D)->data[--((D)->length)]; \ + else { \ + PyErr_SetString(UnpicklingError, "bad pickle data"); \ + (V) = NULL; \ + } \ + } static PyObject * *************** *** 206,215 **** int i, j, l; ! l=self->length-start; ! if (!( r=PyTuple_New(l))) return NULL; ! for (i=start, j=0 ; j < l; i++, j++) PyTuple_SET_ITEM(r, j, self->data[i]); ! self->length=start; return r; } --- 230,241 ---- int i, j, l; ! l = self->length-start; ! r = PyTuple_New(l); ! if (r == NULL) ! return NULL; ! for (i = start, j = 0 ; j < l; i++, j++) PyTuple_SET_ITEM(r, j, self->data[i]); ! self->length = start; return r; } *************** *** 1445,1524 **** #endif static int save_tuple(Picklerobject *self, PyObject *args) { ! PyObject *element = 0, *py_tuple_id = 0; ! int len, i, res = -1; static char tuple = TUPLE; ! ! if (self->write_func(self, &MARKv, 1) < 0) ! goto finally; if ((len = PyTuple_Size(args)) < 0) goto finally; ! for (i = 0; i < len; i++) { ! if (!( element = PyTuple_GET_ITEM((PyTupleObject *)args, i))) ! goto finally; ! if (save(self, element, 0) < 0) ! goto finally; } ! if (!( py_tuple_id = PyLong_FromVoidPtr(args))) goto finally; ! if (len) { if (PyDict_GetItem(self->memo, py_tuple_id)) { ! if (self->bin) { ! static char pop_mark = POP_MARK; ! ! if (self->write_func(self, &pop_mark, 1) < 0) goto finally; ! } ! else { ! static char pop = POP; ! ! for (i = 0; i <= len; i++) { ! if (self->write_func(self, &pop, 1) < 0) ! goto finally; ! } ! } ! if (get(self, py_tuple_id) < 0) goto finally; - res = 0; goto finally; } } ! if (self->write_func(self, &tuple, 1) < 0) { goto finally; } ! if (put(self, args) < 0) goto finally; ! res = 0; finally: Py_XDECREF(py_tuple_id); - return res; } static int - save_empty_tuple(Picklerobject *self, PyObject *args) - { - static char tuple = EMPTY_TUPLE; - - return self->write_func(self, &tuple, 1); - } - - - static int save_list(Picklerobject *self, PyObject *args) { --- 1471,1611 ---- #endif + /* A helper for save_tuple. Push the len elements in tuple t on the stack. */ + static int + store_tuple_elememts(Picklerobject *self, PyObject *t, int len) + { + int i; + int res = -1; /* guilty until proved innocent */ + + assert(PyTuple_Size(t) == len); + + for (i = 0; i < len; i++) { + PyObject *element = PyTuple_GET_ITEM(t, i); + if (element == NULL) + goto finally; + if (save(self, element, 0) < 0) + goto finally; + } + res = 0; + + finally: + return res; + } + + /* Tuples are ubiquitous in the pickle protocols, so many techniques are + * used across protocols to minimize the space needed to pickle them. + * Tuples are also the only builtin immuatable type that can be recursive + * (a tuple can be reached from itself), and that requires some subtle + * magic so that it works in all cases. IOW, this is a long routine. + */ static int save_tuple(Picklerobject *self, PyObject *args) { ! PyObject *py_tuple_id = NULL; ! int len, i; ! int res = -1; static char tuple = TUPLE; ! static char pop = POP; ! static char pop_mark = POP_MARK; ! static char len2opcode[] = {EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3}; if ((len = PyTuple_Size(args)) < 0) goto finally; ! if (len == 0) { ! char c_str[2]; ! if (self->proto) { ! c_str[0] = EMPTY_TUPLE; ! len = 1; ! } ! else { ! c_str[0] = MARK; ! c_str[1] = TUPLE; ! len = 2; ! } ! if (self->write_func(self, c_str, len) >= 0) ! res = 0; ! /* Don't memoize an empty tuple. */ ! goto finally; } ! /* A non-empty tuple. */ ! ! /* id(tuple) isn't in the memo now. If it shows up there after ! * saving the tuple elements, the tuple must be recursive, in ! * which case we'll pop everything we put on the stack, and fetch ! * its value from the memo. ! */ ! py_tuple_id = PyLong_FromVoidPtr(args); ! if (py_tuple_id == NULL) goto finally; ! if (len <= 3 && self->proto >= 2) { ! /* Use TUPLE{1,2,3} opcodes. */ ! if (store_tuple_elememts(self, args, len) < 0) ! goto finally; if (PyDict_GetItem(self->memo, py_tuple_id)) { ! /* pop the len elements */ ! for (i = 0; i < len; ++i) ! if (self->write_func(self, &pop, 1) < 0) goto finally; ! /* fetch from memo */ if (get(self, py_tuple_id) < 0) goto finally; res = 0; goto finally; } + /* Not recursive. */ + if (self->write_func(self, len2opcode + len, 1) < 0) + goto finally; + goto memoize; } ! /* proto < 2 and len > 0, or proto >= 2 and len > 3. ! * Generate MARK elt1 elt2 ... TUPLE ! */ ! if (self->write_func(self, &MARKv, 1) < 0) ! goto finally; ! ! if (store_tuple_elememts(self, args, len) < 0) ! goto finally; ! ! if (PyDict_GetItem(self->memo, py_tuple_id)) { ! /* pop the stack stuff we pushed */ ! if (self->bin) { ! if (self->write_func(self, &pop_mark, 1) < 0) ! goto finally; ! } ! else { ! /* Note that we pop one more than len, to remove ! * the MARK too. ! */ ! for (i = 0; i <= len; i++) ! if (self->write_func(self, &pop, 1) < 0) ! goto finally; ! } ! /* fetch from memo */ ! if (get(self, py_tuple_id) >= 0) ! res = 0; goto finally; } ! /* Not recursive. */ ! if (self->write_func(self, &tuple, 1) < 0) goto finally; ! memoize: ! if (put(self, args) >= 0) ! res = 0; finally: Py_XDECREF(py_tuple_id); return res; } static int save_list(Picklerobject *self, PyObject *args) { *************** *** 1973,1977 **** static int ! save(Picklerobject *self, PyObject *args, int pers_save) { PyTypeObject *type; --- 2060,2064 ---- static int ! save(Picklerobject *self, PyObject *args, int pers_save) { PyTypeObject *type; *************** *** 2029,2035 **** case 't': ! if (type == &PyTuple_Type && PyTuple_Size(args)==0) { ! if (self->bin) res = save_empty_tuple(self, args); ! else res = save_tuple(self, args); goto finally; } --- 2116,2121 ---- case 't': ! if (type == &PyTuple_Type && PyTuple_Size(args) == 0) { ! res = save_tuple(self, args); goto finally; } *************** *** 3194,3202 **** static int ! load_empty_tuple(Unpicklerobject *self) { ! PyObject *tup; ! if (!( tup=PyTuple_New(0))) return -1; PDATA_PUSH(self->stack, tup, -1); return 0; --- 3280,3298 ---- static int ! load_counted_tuple(Unpicklerobject *self, int len) { ! PyObject *tup = PyTuple_New(len); ! if (tup == NULL) ! return -1; ! ! while (--len >= 0) { ! PyObject *element; ! ! PDATA_POP(self->stack, element); ! if (element == NULL) ! return -1; ! PyTuple_SET_ITEM(tup, len, element); ! } PDATA_PUSH(self->stack, tup, -1); return 0; *************** *** 4019,4023 **** case EMPTY_TUPLE: ! if (load_empty_tuple(self) < 0) break; continue; --- 4115,4134 ---- case EMPTY_TUPLE: ! if (load_counted_tuple(self, 0) < 0) ! break; ! continue; ! ! case TUPLE1: ! if (load_counted_tuple(self, 1) < 0) ! break; ! continue; ! ! case TUPLE2: ! if (load_counted_tuple(self, 2) < 0) ! break; ! continue; ! ! case TUPLE3: ! if (load_counted_tuple(self, 3) < 0) break; continue; *************** *** 4347,4351 **** case EMPTY_TUPLE: ! if (load_empty_tuple(self) < 0) break; continue; --- 4458,4477 ---- case EMPTY_TUPLE: ! if (load_counted_tuple(self, 0) < 0) ! break; ! continue; ! ! case TUPLE1: ! if (load_counted_tuple(self, 1) < 0) ! break; ! continue; ! ! case TUPLE2: ! if (load_counted_tuple(self, 2) < 0) ! break; ! continue; ! ! case TUPLE3: ! if (load_counted_tuple(self, 3) < 0) break; continue; From jackjansen@users.sourceforge.net Sun Feb 2 23:00:26 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 02 Feb 2003 15:00:26 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules/file _Filemodule.c,1.16,1.17 filescan.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/file In directory sc8-pr-cvs1:/tmp/cvs-serv3819 Modified Files: _Filemodule.c filescan.py Log Message: The FSAliasFile routines also have an in/out parameter. Index: _Filemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/_Filemodule.c,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** _Filemodule.c 28 Jan 2003 23:29:46 -0000 1.16 --- _Filemodule.c 2 Feb 2003 23:00:19 -0000 1.17 *************** *** 2955,2959 **** Boolean wasAliased; unsigned long mountFlags; ! if (!PyArg_ParseTuple(_args, "bl", &resolveAliasChains, &mountFlags)) --- 2955,2960 ---- Boolean wasAliased; unsigned long mountFlags; ! if (!PyArg_ParseTuple(_args, "O&bl", ! FSRef_Convert, &theRef, &resolveAliasChains, &mountFlags)) *************** *** 2980,2984 **** Boolean targetIsFolder; Boolean wasAliased; ! if (!PyArg_ParseTuple(_args, "b", &resolveAliasChains)) return NULL; --- 2981,2986 ---- Boolean targetIsFolder; Boolean wasAliased; ! if (!PyArg_ParseTuple(_args, "O&b", ! FSRef_Convert, &theRef, &resolveAliasChains)) return NULL; *************** *** 3134,3140 **** PyDoc_STR("(FSRef fromFile, FSRef target) -> (AliasHandle inAlias)")}, {"FSResolveAliasFileWithMountFlags", (PyCFunction)File_FSResolveAliasFileWithMountFlags, 1, ! PyDoc_STR("(Boolean resolveAliasChains, unsigned long mountFlags) -> (FSRef theRef, Boolean targetIsFolder, Boolean wasAliased)")}, {"FSResolveAliasFile", (PyCFunction)File_FSResolveAliasFile, 1, ! PyDoc_STR("(Boolean resolveAliasChains) -> (FSRef theRef, Boolean targetIsFolder, Boolean wasAliased)")}, {"FSUpdateAlias", (PyCFunction)File_FSUpdateAlias, 1, PyDoc_STR("(FSRef fromFile, FSRef target, AliasHandle alias) -> (Boolean wasChanged)")}, --- 3136,3142 ---- PyDoc_STR("(FSRef fromFile, FSRef target) -> (AliasHandle inAlias)")}, {"FSResolveAliasFileWithMountFlags", (PyCFunction)File_FSResolveAliasFileWithMountFlags, 1, ! PyDoc_STR("(FSRef theRef, Boolean resolveAliasChains, unsigned long mountFlags) -> (FSRef theRef, Boolean targetIsFolder, Boolean wasAliased)")}, {"FSResolveAliasFile", (PyCFunction)File_FSResolveAliasFile, 1, ! PyDoc_STR("(FSRef theRef, Boolean resolveAliasChains) -> (FSRef theRef, Boolean targetIsFolder, Boolean wasAliased)")}, {"FSUpdateAlias", (PyCFunction)File_FSUpdateAlias, 1, PyDoc_STR("(FSRef fromFile, FSRef target, AliasHandle alias) -> (Boolean wasChanged)")}, Index: filescan.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/filescan.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** filescan.py 12 Jan 2003 23:01:46 -0000 1.7 --- filescan.py 2 Feb 2003 23:00:21 -0000 1.8 *************** *** 173,176 **** --- 173,179 ---- [('FSSpec_ptr', 'theSpec', 'InOutMode')]), + ([('FSRef', 'theRef', 'OutMode')], + [('FSRef_ptr', 'theRef', 'InOutMode')]), + # The optional FSSpec to all ResolveAlias and NewAlias methods ([('FSSpec_ptr', 'fromFile', 'InMode')], From jackjansen@users.sourceforge.net Sun Feb 2 23:03:52 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 02 Feb 2003 15:03:52 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac buildtools.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv5154 Modified Files: buildtools.py Log Message: Getting rid of macfs usage and almost all FSSpecs. Untested on MacOS9. Index: buildtools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/buildtools.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** buildtools.py 9 Jan 2003 10:47:20 -0000 1.2 --- buildtools.py 2 Feb 2003 23:03:50 -0000 1.3 *************** *** 6,12 **** import imp import marshal - import macfs from Carbon import Res ! import MACFS import MacOS import macostools --- 6,12 ---- import imp import marshal from Carbon import Res ! import Carbon.Files ! import Carbon.File import MacOS import macostools *************** *** 39,42 **** --- 39,44 ---- WRITE = 2 + # Parameter for FSOpenResourceFile + RESOURCE_FORK_NAME=Carbon.File.FSGetResourceForkName() def findtemplate(template=None): *************** *** 51,57 **** file = os.path.join(p, template) try: ! file, d1, d2 = macfs.ResolveAliasFile(file) break ! except (macfs.error, ValueError): continue else: --- 53,59 ---- file = os.path.join(p, template) try: ! file, d1, d2 = Carbon.File.FSResolveAliasFile(file, 1) break ! except (Carbon.File.error, ValueError): continue else: *************** *** 146,152 **** raise BuildError, "Extra files only allowed for MachoPython applets" # Create FSSpecs for the various files ! template_fss = macfs.FSSpec(template) ! template_fss, d1, d2 = macfs.ResolveAliasFile(template_fss) ! dest_fss = macfs.FSSpec(destname) # Copy data (not resources, yet) from the template --- 148,153 ---- raise BuildError, "Extra files only allowed for MachoPython applets" # Create FSSpecs for the various files ! template_fsr, d1, d2 = Carbon.File.FSResolveAliasFile(template, 1) ! template = template_fsr.as_pathname() # Copy data (not resources, yet) from the template *************** *** 172,184 **** progress.set(20) try: ! output = Res.FSpOpenResFile(dest_fss, WRITE) except MacOS.Error: ! Res.FSpCreateResFile(destname, '????', 'APPL', MACFS.smAllScripts) ! output = Res.FSpOpenResFile(dest_fss, WRITE) # Copy the resources from the target specific resource template, if any typesfound, ownertype = [], None try: ! input = Res.FSpOpenResFile(rsrcname, READ) except (MacOS.Error, ValueError): pass --- 173,186 ---- progress.set(20) try: ! output = Res.FSOpenResourceFile(destname, RESOURCE_FORK_NAME, WRITE) except MacOS.Error: ! destdir, destfile = os.path.split(destname) ! Res.FSCreateResourceFile(destdir, destfile, RESOURCE_FORK_NAME) ! output = Res.FSOpenResourceFile(destname, RESOURCE_FORK_NAME, WRITE) # Copy the resources from the target specific resource template, if any typesfound, ownertype = [], None try: ! input = Res.FSOpenResourceFile(rsrcname, RESOURCE_FORK_NAME, READ) except (MacOS.Error, ValueError): pass *************** *** 205,209 **** # Copy the resources from the template ! input = Res.FSpOpenResFile(template_fss, READ) dummy, tmplowner = copyres(input, output, skiptypes, 1, progress) --- 207,211 ---- # Copy the resources from the template ! input = Res.FSOpenResourceFile(template, RESOURCE_FORK_NAME, READ) dummy, tmplowner = copyres(input, output, skiptypes, 1, progress) *************** *** 258,270 **** Res.CloseResFile(output) ! # Now set the creator, type and bundle bit of the destination ! dest_finfo = dest_fss.GetFInfo() dest_finfo.Creator = ownertype dest_finfo.Type = 'APPL' ! dest_finfo.Flags = dest_finfo.Flags | MACFS.kHasBundle | MACFS.kIsShared ! dest_finfo.Flags = dest_finfo.Flags & ~MACFS.kHasBeenInited ! dest_fss.SetFInfo(dest_finfo) ! macostools.touched(dest_fss) if progress: progress.label("Done.") --- 260,274 ---- Res.CloseResFile(output) ! # Now set the creator, type and bundle bit of the destination. ! # Done with FSSpec's, FSRef FInfo isn't good enough yet (2.3a1+) ! dset_fss = Carbon.File.FSSpec(destname) ! dest_finfo = dest_fss.FSpGetFInfo() dest_finfo.Creator = ownertype dest_finfo.Type = 'APPL' ! dest_finfo.Flags = dest_finfo.Flags | Carbon.Files.kHasBundle | Carbon.Files.kIsShared ! dest_finfo.Flags = dest_finfo.Flags & ~Carbon.Files.kHasBeenInited ! dest_fss.FSpSetFInfo(dest_finfo) ! macostools.touched(destname) if progress: progress.label("Done.") From doerwalter@users.sourceforge.net Sun Feb 2 23:08:30 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Sun, 02 Feb 2003 15:08:30 -0800 Subject: [Python-checkins] python/dist/src/Lib codecs.py,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv6591/Lib Modified Files: codecs.py Log Message: Fix typos. Index: codecs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/codecs.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** codecs.py 30 Dec 2002 23:36:02 -0000 1.31 --- codecs.py 2 Feb 2003 23:08:27 -0000 1.32 *************** *** 281,285 **** .readline() method -- there is currently no support for line breaking using the codec decoder due to lack of line ! buffering. Sublcasses should however, if possible, try to implement this method using their own knowledge of line breaking. --- 281,285 ---- .readline() method -- there is currently no support for line breaking using the codec decoder due to lack of line ! buffering. Subclasses should however, if possible, try to implement this method using their own knowledge of line breaking. *************** *** 540,549 **** Files are always opened in binary mode, even if no binary mode ! was specified. Thisis done to avoid data loss due to encodings using 8-bit values. The default file mode is 'rb' meaning to open the file in binary read mode. encoding specifies the encoding which is to be used for the ! the file. errors may be given to define the error handling. It defaults --- 540,549 ---- Files are always opened in binary mode, even if no binary mode ! was specified. This is done to avoid data loss due to encodings using 8-bit values. The default file mode is 'rb' meaning to open the file in binary read mode. encoding specifies the encoding which is to be used for the ! file. errors may be given to define the error handling. It defaults *************** *** 671,675 **** """ Creates an encoding map from a decoding map. ! If a target mapping in the decoding map occurrs multiple times, then that target is mapped to None (undefined mapping), causing an exception when encountered by the charmap codec --- 671,675 ---- """ Creates an encoding map from a decoding map. ! If a target mapping in the decoding map occurs multiple times, then that target is mapped to None (undefined mapping), causing an exception when encountered by the charmap codec From doerwalter@users.sourceforge.net Sun Feb 2 23:37:08 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Sun, 02 Feb 2003 15:37:08 -0800 Subject: [Python-checkins] python/dist/src README,1.167,1.168 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv15940 Modified Files: README Log Message: Fix typos. Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/README,v retrieving revision 1.167 retrieving revision 1.168 diff -C2 -d -r1.167 -r1.168 *** README 15 Jan 2003 16:04:43 -0000 1.167 --- README 2 Feb 2003 23:37:05 -0000 1.168 *************** *** 135,139 **** If you have a proposal to change Python, it's best to submit a Python Enhancement Proposal (PEP) first. All current PEPs, as well as ! guidelines for submitting a new PEP, are list at http://python.sourceforge.net/peps/. --- 135,139 ---- If you have a proposal to change Python, it's best to submit a Python Enhancement Proposal (PEP) first. All current PEPs, as well as ! guidelines for submitting a new PEP, are listed at http://python.sourceforge.net/peps/. *************** *** 286,290 **** you need to first make sure that the library is available on your system. Then, you need to instruct the dynamic loader how ! to find it. You can chose any of the following strategies: 1. When compiling Python, set LD_RUN_PATH to the directories --- 286,290 ---- you need to first make sure that the library is available on your system. Then, you need to instruct the dynamic loader how ! to find it. You can choose any of the following strategies: 1. When compiling Python, set LD_RUN_PATH to the directories *************** *** 546,550 **** To do this, run "./configure --with-threads=no" including any other options you need (--prefix, etc.). Then in Modules/Setup ! uncomment the lines: #SSL=/usr/local/ssl --- 546,550 ---- To do this, run "./configure --with-threads=no" including any other options you need (--prefix, etc.). Then in Modules/Setup ! uncomment the lines: #SSL=/usr/local/ssl *************** *** 690,694 **** the configure.in file and are confident that the patch works, please send in the patch. (Don't bother patching the configure script itself ! -- it is regenerated each the configure.in file changes.) Compiler switches for threads --- 690,694 ---- the configure.in file and are confident that the patch works, please send in the patch. (Don't bother patching the configure script itself ! -- it is regenerated each time the configure.in file changes.) Compiler switches for threads *************** *** 821,825 **** Note that on Linux, gprof apparently does not work for shared libraries. The Makefile/Setup mechanism can be used to compile and ! link most extension module statically. --- 821,825 ---- Note that on Linux, gprof apparently does not work for shared libraries. The Makefile/Setup mechanism can be used to compile and ! link most extension modules statically. From doerwalter@users.sourceforge.net Sun Feb 2 23:39:48 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Sun, 02 Feb 2003 15:39:48 -0800 Subject: [Python-checkins] python/dist/src/Tools/scripts gencodec.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv16925/Tools/scripts Modified Files: gencodec.py Log Message: Fix comment typo. Index: gencodec.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/gencodec.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** gencodec.py 11 Sep 2002 20:36:01 -0000 1.7 --- gencodec.py 2 Feb 2003 23:39:45 -0000 1.8 *************** *** 96,100 **** enc2uni[enc] = (uni,comment) # If there are more identity-mapped entries than unmapped entries, ! # it pays to generate an identity dictionary first, add add explicit # mappings to None for the rest if len(identity)>=len(unmapped): --- 96,100 ---- enc2uni[enc] = (uni,comment) # If there are more identity-mapped entries than unmapped entries, ! # it pays to generate an identity dictionary first, and add explicit # mappings to None for the rest if len(identity)>=len(unmapped): From montanaro@users.sourceforge.net Mon Feb 3 01:25:04 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 17:25:04 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv25499 Modified Files: test_csv.py Log Message: Add a few tests for writing array objects. Writing ints or chars works, writing floats doesn't. It appears what is written is neither the str() or the repr() of the float. Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_csv.py 2 Feb 2003 11:57:28 -0000 1.4 --- test_csv.py 3 Feb 2003 01:25:02 -0000 1.5 *************** *** 125,128 **** --- 125,158 ---- self.assertRaises(csv.CSVError, writer.write, {"f1": 10, "f3": "abc"}) + class TestArrayWrites(unittest.TestCase): + def test_int_write(self): + import array + contents = [(20-i) for i in range(20)] + a = array.array('i', contents) + fileobj = StringIO() + writer = csv.writer(fileobj, dialect="excel") + writer.write(a) + expected = ",".join([str(i) for i in contents])+"\r\n" + self.assertEqual(fileobj.getvalue(), expected) + + def test_float_write(self): + import array + contents = [(20-i)*0.1 for i in range(20)] + a = array.array('f', contents) + fileobj = StringIO() + writer = csv.writer(fileobj, dialect="excel") + writer.write(a) + expected = ",".join([str(i) for i in contents])+"\r\n" + self.assertEqual(fileobj.getvalue(), expected) + + def test_char_write(self): + import array, string + a = array.array('c', string.letters) + fileobj = StringIO() + writer = csv.writer(fileobj, dialect="excel") + writer.write(a) + expected = ",".join(string.letters)+"\r\n" + self.assertEqual(fileobj.getvalue(), expected) + def _testclasses(): mod = sys.modules[__name__] From gvanrossum@users.sourceforge.net Mon Feb 3 01:32:35 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Sun, 02 Feb 2003 17:32:35 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv28280 Modified Files: test_datetime.py Log Message: cPickle now implements enough of protocol 2 to enable all cross-pickling tests. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** test_datetime.py 1 Feb 2003 02:54:14 -0000 1.33 --- test_datetime.py 3 Feb 2003 01:32:33 -0000 1.34 *************** *** 24,34 **** (cPickle, cPickle, 0), (cPickle, cPickle, 1), ! ## (cPickle, cPickle, 2), (pickle, cPickle, 0), (pickle, cPickle, 1), ! ## (pickle, cPickle, 2), (cPickle, pickle, 0), (cPickle, pickle, 1), ! ## (cPickle, pickle, 2), ] --- 24,34 ---- (cPickle, cPickle, 0), (cPickle, cPickle, 1), ! (cPickle, cPickle, 2), (pickle, cPickle, 0), (pickle, cPickle, 1), ! (pickle, cPickle, 2), (cPickle, pickle, 0), (cPickle, pickle, 1), ! (cPickle, pickle, 2), ] From montanaro@users.sourceforge.net Mon Feb 3 01:33:02 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 17:33:02 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv28480 Modified Files: test_csv.py Log Message: whoops - test was wrong. Should have tested writing doubles, not floats. Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_csv.py 3 Feb 2003 01:25:02 -0000 1.5 --- test_csv.py 3 Feb 2003 01:33:00 -0000 1.6 *************** *** 136,143 **** self.assertEqual(fileobj.getvalue(), expected) ! def test_float_write(self): import array contents = [(20-i)*0.1 for i in range(20)] ! a = array.array('f', contents) fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") --- 136,143 ---- self.assertEqual(fileobj.getvalue(), expected) ! def test_double_write(self): import array contents = [(20-i)*0.1 for i in range(20)] ! a = array.array('d', contents) fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") From montanaro@users.sourceforge.net Mon Feb 3 01:42:24 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 17:42:24 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv31029 Modified Files: test_csv.py Log Message: Should be generating array expected values from the array, not the data fed into the array. Added a test of writing single-precision floats (which won't work if you generate the expected values from the inputs to the array constructor). Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_csv.py 3 Feb 2003 01:33:00 -0000 1.6 --- test_csv.py 3 Feb 2003 01:42:22 -0000 1.7 *************** *** 133,137 **** writer = csv.writer(fileobj, dialect="excel") writer.write(a) ! expected = ",".join([str(i) for i in contents])+"\r\n" self.assertEqual(fileobj.getvalue(), expected) --- 133,137 ---- writer = csv.writer(fileobj, dialect="excel") writer.write(a) ! expected = ",".join([str(i) for i in a])+"\r\n" self.assertEqual(fileobj.getvalue(), expected) *************** *** 143,147 **** writer = csv.writer(fileobj, dialect="excel") writer.write(a) ! expected = ",".join([str(i) for i in contents])+"\r\n" self.assertEqual(fileobj.getvalue(), expected) --- 143,157 ---- writer = csv.writer(fileobj, dialect="excel") writer.write(a) ! expected = ",".join([str(i) for i in a])+"\r\n" ! self.assertEqual(fileobj.getvalue(), expected) ! ! def test_float_write(self): ! import array ! contents = [(20-i)*0.1 for i in range(20)] ! a = array.array('f', contents) ! fileobj = StringIO() ! writer = csv.writer(fileobj, dialect="excel") ! writer.write(a) ! expected = ",".join([str(i) for i in a])+"\r\n" self.assertEqual(fileobj.getvalue(), expected) *************** *** 152,156 **** writer = csv.writer(fileobj, dialect="excel") writer.write(a) ! expected = ",".join(string.letters)+"\r\n" self.assertEqual(fileobj.getvalue(), expected) --- 162,166 ---- writer = csv.writer(fileobj, dialect="excel") writer.write(a) ! expected = ",".join(a)+"\r\n" self.assertEqual(fileobj.getvalue(), expected) From montanaro@users.sourceforge.net Mon Feb 3 02:07:39 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 18:07:39 -0800 Subject: [Python-checkins] python/nondist/peps pep-0305.txt,1.10,1.11 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv15396 Modified Files: pep-0305.txt Log Message: default dialect is now "excel", not "excel2000". Index: pep-0305.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0305.txt,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** pep-0305.txt 2 Feb 2003 12:25:23 -0000 1.10 --- pep-0305.txt 3 Feb 2003 02:07:37 -0000 1.11 *************** *** 90,94 **** writing. The basic reading interface is:: ! obj = reader(iterable [, dialect='excel2000'] [optional keyword args]) --- 90,94 ---- writing. The basic reading interface is:: ! obj = reader(iterable [, dialect='excel'] [optional keyword args]) *************** *** 106,110 **** The writing interface is similar:: ! obj = writer(fileobj [, dialect='excel2000'], [, fieldnames=seq] [optional keyword args]) --- 106,110 ---- The writing interface is similar:: ! obj = writer(fileobj [, dialect='excel'], [, fieldnames=seq] [optional keyword args]) *************** *** 165,169 **** follows:: ! class exceltsv(csv.excel2000): delimiter = '\t' --- 165,169 ---- follows:: ! class exceltsv(csv.excel): delimiter = '\t' From montanaro@users.sourceforge.net Mon Feb 3 02:25:28 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 18:25:28 -0800 Subject: [Python-checkins] python/nondist/peps pep-0305.txt,1.11,1.12 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv22612 Modified Files: pep-0305.txt Log Message: set_dialect is the wrong name. It conveys the notion of a single dialect. register_dialect is better. Index: pep-0305.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0305.txt,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** pep-0305.txt 3 Feb 2003 02:07:37 -0000 1.11 --- pep-0305.txt 3 Feb 2003 02:25:26 -0000 1.12 *************** *** 170,174 **** Three functions are defined in the API to set, get and list dialects:: ! set_dialect(name, dialect) dialect = get_dialect(name) known_dialects = list_dialects() --- 170,174 ---- Three functions are defined in the API to set, get and list dialects:: ! register_dialect(name, dialect) dialect = get_dialect(name) known_dialects = list_dialects() *************** *** 177,181 **** formatting parameters defined in the next section. The list_dialects() function returns all the registered dialect names as ! given in previous set_dialect() calls (both predefined and user-defined). --- 177,181 ---- formatting parameters defined in the next section. The list_dialects() function returns all the registered dialect names as ! given in previous register_dialect() calls (both predefined and user-defined). *************** *** 187,191 **** formatting parameters, specified as keyword parameters. The parameters are also the keys for the input and output mapping objects ! for the set_dialect() and get_dialect() module functions. - ``quotechar`` specifies a one-character string to use as the quoting --- 187,191 ---- formatting parameters, specified as keyword parameters. The parameters are also the keys for the input and output mapping objects ! for the register_dialect() and get_dialect() module functions. - ``quotechar`` specifies a one-character string to use as the quoting From montanaro@users.sourceforge.net Mon Feb 3 02:34:44 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 18:34:44 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv25115 Modified Files: csv.py Log Message: set_dialect is a bad name. register_dialect is better. Check that dialect being registered is subclass of Dialect. save an instance of the class, not the class itself. Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** csv.py 2 Feb 2003 12:05:07 -0000 1.12 --- csv.py 3 Feb 2003 02:34:42 -0000 1.13 *************** *** 89,94 **** pass ! def set_dialect(name, dialect): ! dialects[name] = dialect def get_dialect(name): --- 89,96 ---- pass ! def register_dialect(name, dialect): ! if not issubclass(dialect, Dialect): ! raise TypeError, "dialect not a subclass of Dialect" ! dialects[name] = dialect() def get_dialect(name): From montanaro@users.sourceforge.net Mon Feb 3 02:35:41 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 18:35:41 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv25351 Modified Files: test_csv.py Log Message: add a few tests of the dialect registration stuff. Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_csv.py 3 Feb 2003 01:42:22 -0000 1.7 --- test_csv.py 3 Feb 2003 02:35:38 -0000 1.8 *************** *** 165,168 **** --- 165,187 ---- self.assertEqual(fileobj.getvalue(), expected) + class TestDialects(unittest.TestCase): + def test_register(self): + class myexceltsv(csv.excel): + delimiter = "\t" + csv.register_dialect("myexceltsv", myexceltsv) + self.assertEqual(isinstance(csv.get_dialect("myexceltsv"), + myexceltsv), 1==1) + del csv.dialects["myexceltsv"] + + def test_get(self): + self.assertEqual(isinstance(csv.get_dialect("excel"), + csv.excel), 1==1) + + def test_bad_register(self): + class myexceltsv: + delimiter = "\t" + self.assertRaises(TypeError, csv.register_dialect, + "myexceltsv", myexceltsv) + def _testclasses(): mod = sys.modules[__name__] From montanaro@users.sourceforge.net Mon Feb 3 02:43:10 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 18:43:10 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.11,1.12 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv27527 Modified Files: _csv.c Log Message: make it work with Python 2.2 Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** _csv.c 2 Feb 2003 12:58:40 -0000 1.11 --- _csv.c 3 Feb 2003 02:43:08 -0000 1.12 *************** *** 17,20 **** --- 17,41 ---- #include "structmember.h" + /* begin 2.2 compatibility macros */ + #ifndef PyDoc_STRVAR + /* Define macros for inline documentation. */ + #define PyDoc_VAR(name) static char name[] + #define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str) + #ifdef WITH_DOC_STRINGS + #define PyDoc_STR(str) str + #else + #define PyDoc_STR(str) "" + #endif + #endif /* ifndef PyDoc_STRVAR */ + + #ifndef PyMODINIT_FUNC + # if defined(__cplusplus) + # define PyMODINIT_FUNC extern "C" void + # else /* __cplusplus */ + # define PyMODINIT_FUNC void + # endif /* __cplusplus */ + #endif + /* end 2.2 compatibility macros */ + static PyObject *error_obj; /* CSV exception */ From montanaro@users.sourceforge.net Mon Feb 3 02:52:06 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 18:52:06 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv30005 Modified Files: csv.py Log Message: The dialects dict shouldn't be part of the public API. Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** csv.py 3 Feb 2003 02:34:42 -0000 1.13 --- csv.py 3 Feb 2003 02:52:04 -0000 1.14 *************** *** 19,23 **** delimiter = '\t' ! dialects = { 'excel': excel(), 'excel-tab': excel_tab(), --- 19,23 ---- delimiter = '\t' ! _dialects = { 'excel': excel(), 'excel-tab': excel_tab(), *************** *** 30,34 **** else: try: ! dialect_obj = dialects[dialect] except KeyError: raise CSVError('Unknown dialect') --- 30,34 ---- else: try: ! dialect_obj = _dialects[dialect] except KeyError: raise CSVError('Unknown dialect') *************** *** 92,106 **** if not issubclass(dialect, Dialect): raise TypeError, "dialect not a subclass of Dialect" ! dialects[name] = dialect() def get_dialect(name): ! return dialects[name] def list_dialects(): ! return dialects.keys() # An alternate way of populating the dialects dictionary... #def _init_dialects(): ! # global dialects # mod = sys.modules[__name__] # for name in dir(mod): --- 92,106 ---- if not issubclass(dialect, Dialect): raise TypeError, "dialect not a subclass of Dialect" ! _dialects[name] = dialect() def get_dialect(name): ! return _dialects[name] def list_dialects(): ! return _dialects.keys() # An alternate way of populating the dialects dictionary... #def _init_dialects(): ! # global _dialects # mod = sys.modules[__name__] # for name in dir(mod): *************** *** 109,113 **** # if issubclass(attr, Dialect) and attr is not Dialect: # dialect = attr() ! # dialects[dialect.name] = dialect # except TypeError: # pass --- 109,113 ---- # if issubclass(attr, Dialect) and attr is not Dialect: # dialect = attr() ! # _dialects[dialect.name] = dialect # except TypeError: # pass From montanaro@users.sourceforge.net Mon Feb 3 02:54:32 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 18:54:32 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv30709 Modified Files: csv.py Log Message: define the public API with __all__ remove the OCcsv class from the public API Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** csv.py 3 Feb 2003 02:52:04 -0000 1.14 --- csv.py 3 Feb 2003 02:54:30 -0000 1.15 *************** *** 2,5 **** --- 2,9 ---- from _csv import Error as CSVError + __all__ [ "QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", + "CSVError", "Dialect", "excel", "excel_tab", "reader", "writer", + "register_dialect", "get_dialect", "list_dialects"] + QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE = range(4) *************** *** 24,28 **** } ! class OCcsv: def __init__(self, dialect, **options): if isinstance(dialect, Dialect): --- 28,32 ---- } ! class _OCcsv: def __init__(self, dialect, **options): if isinstance(dialect, Dialect): *************** *** 41,48 **** self.parser = _csv.parser(**parser_options) ! class reader(OCcsv): def __init__(self, iterobj, dialect = 'excel', **options): self.iterobj = iter(iterobj) ! OCcsv.__init__(self, dialect, **options) def __iter__(self): --- 45,52 ---- self.parser = _csv.parser(**parser_options) ! class reader(_OCcsv): def __init__(self, iterobj, dialect = 'excel', **options): self.iterobj = iter(iterobj) ! _OCcsv.__init__(self, dialect, **options) def __iter__(self): *************** *** 55,63 **** return fields ! class writer(OCcsv): def __init__(self, fileobj, dialect='excel', fieldnames=None, **options): self.fileobj = fileobj self.fieldnames = fieldnames ! OCcsv.__init__(self, dialect, **options) def write(self, fields): --- 59,67 ---- return fields ! class writer(_OCcsv): def __init__(self, fileobj, dialect='excel', fieldnames=None, **options): self.fileobj = fileobj self.fieldnames = fieldnames ! _OCcsv.__init__(self, dialect, **options) def write(self, fields): From montanaro@users.sourceforge.net Mon Feb 3 02:55:21 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 18:55:21 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv31143 Modified Files: csv.py Log Message: doh! a little quick with the trigger there, Skip! Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** csv.py 3 Feb 2003 02:54:30 -0000 1.15 --- csv.py 3 Feb 2003 02:55:19 -0000 1.16 *************** *** 2,8 **** from _csv import Error as CSVError ! __all__ [ "QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", ! "CSVError", "Dialect", "excel", "excel_tab", "reader", "writer", ! "register_dialect", "get_dialect", "list_dialects"] QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE = range(4) --- 2,8 ---- from _csv import Error as CSVError ! __all__ = [ "QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", ! "CSVError", "Dialect", "excel", "excel_tab", "reader", "writer", ! "register_dialect", "get_dialect", "list_dialects"] QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE = range(4) From montanaro@users.sourceforge.net Mon Feb 3 02:56:22 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 18:56:22 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv31414 Modified Files: test_csv.py Log Message: the dialects dict is no longer part of the public API Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** test_csv.py 3 Feb 2003 02:35:38 -0000 1.8 --- test_csv.py 3 Feb 2003 02:56:20 -0000 1.9 *************** *** 172,176 **** self.assertEqual(isinstance(csv.get_dialect("myexceltsv"), myexceltsv), 1==1) ! del csv.dialects["myexceltsv"] def test_get(self): --- 172,176 ---- self.assertEqual(isinstance(csv.get_dialect("myexceltsv"), myexceltsv), 1==1) ! del csv._dialects["myexceltsv"] def test_get(self): From montanaro@users.sourceforge.net Mon Feb 3 03:01:50 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 19:01:50 -0800 Subject: [Python-checkins] python/nondist/peps pep-0305.txt,1.12,1.13 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv32647 Modified Files: pep-0305.txt Log Message: zap incorrect statement about formatting parameters and the dialect registry. Index: pep-0305.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0305.txt,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** pep-0305.txt 3 Feb 2003 02:25:26 -0000 1.12 --- pep-0305.txt 3 Feb 2003 03:01:48 -0000 1.13 *************** *** 185,191 **** Both the reader and writer constructors take several specific ! formatting parameters, specified as keyword parameters. The ! parameters are also the keys for the input and output mapping objects ! for the register_dialect() and get_dialect() module functions. - ``quotechar`` specifies a one-character string to use as the quoting --- 185,189 ---- Both the reader and writer constructors take several specific ! formatting parameters, specified as keyword parameters. - ``quotechar`` specifies a one-character string to use as the quoting From montanaro@users.sourceforge.net Mon Feb 3 03:09:30 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 19:09:30 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv libcsv.tex,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv2201 Added Files: libcsv.tex Log Message: First cut at a libref section. I'm certain there are mistakes, but this gets some ink on the paper. --- NEW FILE: libcsv.tex --- \section{\module{csv} --- CSV File Reading and Writing} \declaremodule{standard}{csv} \modulesynopsis{Write and read tabular data to and from delimited files.} \index{csv} \indexii{data}{tabular} The \module{csv} module implements classes to read and write tabular data. The so-called CSV (Comma Separated Values) format is the most common import and export format for spreadsheets and databases. While the delimiters and quoting characters vary, the overall format is similar enough that it is possible to write a single module which can manipulate such data. There is no ``CSV standard'', so the format is operationally defined by the many applications which read and write it. The lack of a standard means there can be subtle differences in the data produced and consumed by different applications. These differences can be maddeningly subtle. The \module{csv} allows programmers to say, ``write this data in the format preferred by Excel (tm),'' without knowing all the fiddly little details of the CSV format used by Excel. Programmers can also easily define their own CSV formats. \subsection{Relationship to other Python modules} The csv module reads and writes sequences. It can also read data and return the rows as dicts. Sequence types other than lists and tuples (e.g. \code{array} objects) can be written. To make it as easy as possible to interface with modules which implement the DB API, the value None is written as the empty string. While this isn't a reversible transformation, it makes it easier to dump SQL NULL data values to CSV files without preprocessing the data returned from a {}\code{cursor.fetch*()} call. The \module{csv} module defines the following classes. \begin{classdesc}{reader}{iterable\optional{, dialect="excel"} \optional{, fmtparam}} Create a reader object which will iterate over lines in the given {}\var{csvfile}. An optional \var{dialect} parameter can be given which is used to define a set of parameters specific to a particular CSV dialect. The other optional \var{fmtparam} keyword arguments can be given to override individual formatting parameters in the current dialect. For more information about the dialect and formatting parameters, see section {}\ref{fmt-params}, ``Dialects and Formatting Parameters'' for details of these parameters. \end{classdesc} \begin{classdesc}{writer}{fileobj\optional{, dialect="excel"} \optional{, fieldnames} \optional{, fmtparam}} Create a writer object responsible for converting the user's data into delimited strings on the given file-like object. An optional \var{dialect} parameter can be given which is used to define a set of parameters specific to a particular CSV dialect. If a sequence of strings is given as the optional \var{fieldnames} parameter, the writer will use them to properly order mapping objects passed to the object's \method{write} methods. The other optional \var{fmtparam} keyword arguments can be given to override individual formatting parameters in the current dialect. For more information about the dialect and formatting parameters, see section {}\ref{fmt-params}, ``Dialects and Formatting Parameters'' for details of these parameters. \end{classdesc} The \module{csv} module defines the following functions. \begin{funcdesc}{register_dialect}{name, dialect} Associate \var{dialect} with \var{name}. \var{dialect} must be a subclass of \class{csv.Dialect}. \var{name} must be a string or Unicode object. \end{funcdesc} \begin{funcdesc}{get_dialect}{name} Return the dialect associated with \var{name}. A \exception{KeyError} is raised if \var{name} is not a registered dialect name. \end{funcdesc} \begin{funcdesc}{list_dialects}{} Return the names of all registered dialects. \end{funcdesc} The \module{csv} module defines the following constants. \begin{datadesc}{QUOTE_ALWAYS} Instructs \class{writer} objects to quote all fields. \end{datadesc} \begin{datadesc}{QUOTE_MINIMAL} Instructs \class{writer} objects to only quote those fields which contain the current \var{delimiter} or begin with the current \var{quotechar}. \end{datadesc} \begin{datadesc}{QUOTE_NONNUMERIC} Instructs \class{writer} objects to quote all non-numeric fields. \end{datadesc} \begin{datadesc}{QUOTE_NONE} Instructs \class{writer} objects to never quote fields. When the current {}\var{delimiter} occurs in output data it is preceded by the current {}\var{escapechar} character. When QUOTE_NONE is in effect, it is an error not to have a single-character \var{escapechar} defined, even if no data to be written contains the \var{delimiter} character. \end{datadesc} \subsection{Dialects and Formatting Parameters\label{fmt-params}} To make it easier to specify the format of input and output records, specific formatting parameters are grouped together into dialects. A dialect is a subclass of the \class{Dialect} class having a set of specific methods and a single \method{validate} method. When creating \class{reader} or \class{writer} objects, the programmer can specify a string or a subclass of the \class{Dialect} class as the dialect parameter. In addition to, or instead of, the \var{dialect} parameter, the programmer can also specify individual formatting parameters, described in the following section. \subsubsection{Formatting Parameters} Both the \class{reader} and \class{writer} classes take several specific formatting parameters, specified as keyword parameters. \begin{description} \item{quotechar}{specifies a one-character string to use as the quoting character. It defaults to \code{"}.} \item{delimiter}{specifies a one-character string to use as the field separator. It defaults to \code{,}.} \item{escapechar}{specifies a one-character string used to escape the delimiter when quotechar is set to \var{None}.} \item{skipinitialspace}{specifies how to interpret whitespace which immediately follows a delimiter. It defaults to False, which means that whitespace immediately following a delimiter is part of the following field.} \item{lineterminator}{specifies the character sequence which should terminate rows.} \item{quoting}{controls when quotes should be generated by the writer. It can take on any of the following module constants:} \begin{description} \item{QUOTE_MINIMAL}{means only when required, for example, when a field contains either the quotechar or the delimiter.} \item{QUOTE_ALL}{means that quotes are always placed around all fields.} \item{QUOTE_NONNUMERIC}{means that quotes are always placed around fields which contain characters other than [+-0-9.].} \item{QUOTE_NONE}{means that quotes are never placed around fields. Instead, the \var{escapechar} is used to escape any instances of the \var{delimiter} which occurs in the data.} \end{description} \item{doublequote}{controls the handling of quotes inside fields. When \var{True}, two consecutive quotes are interpreted as one during read, and when writing, each quote is written as two quotes.} \end{description} \subsection{Reader Objects} \class{Reader} objects have the following public methods. \begin{methoddesc}{next}{} Return the next row of the reader's iterable object as a list, parsed according to the current dialect. \end{methoddesc} \subsection{Writer Objects} \class{Writer} objects have the following public methods. \begin{methoddesc}{write}{row} Write the \var{row} parameter to the writer's file object, formatted according to the current dialect. \end{methoddesc} \begin{methoddesc}{writelines}{rows} Write all the \var{rows} parameters to the writer's file object, formatted according to the current dialect. \end{methoddesc} \begin{methoddesc}{close}{} Close the underlying file object. \end{methoddesc} \subsection{Examples} The ``hello world'' of csv reading is \begin{verbatim} reader = csv.reader(file("some.csv")) for row in reader: print row \end{verbatim} The corresponding simplest possible writing example is \begin{verbatim} writer = csv.writer(file("some.csv", "w")) for row in someiterable: writer.write(row) \end{verbatim} Both the \class{reader} and \class{writer} classes accept a number of optional arguments which are used to tailor them to the dialect of the input or output file. From montanaro@users.sourceforge.net Mon Feb 3 03:56:38 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 19:56:38 -0800 Subject: [Python-checkins] python/dist/src/Doc/api concrete.tex,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory sc8-pr-cvs1:/tmp/cvs-serv13331 Modified Files: concrete.tex Log Message: Add PyFloat_FromString. Left the char **pend argument out of the description since while there, it is useless and ignored, according to Tim's commen. (PyInt_FromString is also not described, but PyLong_FromString is. Is the former deprecated?) Index: concrete.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/concrete.tex,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** concrete.tex 22 Oct 2002 20:20:20 -0000 1.18 --- concrete.tex 3 Feb 2003 03:56:36 -0000 1.19 *************** *** 318,321 **** --- 318,326 ---- \end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyFloat_FromString}{PyObject *str} + Creates a \ctype{PyFloatObject} object based on the string value in + \var{str}, or \NULL{} on failure. + \end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyFloat_FromDouble}{double v} Creates a \ctype{PyFloatObject} object from \var{v}, or \NULL{} on From tim.one@comcast.net Mon Feb 3 04:17:24 2003 From: tim.one@comcast.net (Tim Peters) Date: Sun, 02 Feb 2003 23:17:24 -0500 Subject: [Python-checkins] python/dist/src/Doc/api concrete.tex,1.18,1.19 In-Reply-To: Message-ID: [montanaro@users.sourceforge.net] > Modified Files: > concrete.tex > Log Message: > Add PyFloat_FromString. Left the char **pend argument out of the > description since while there, it is useless and ignored, > according to Tim's comment. You still have to pass it, though! We can't get rid of it without breaking backward compatibility, but it does no good to pass anything other than NULL. The docs should tell the plain truth here -- sometimes reality isn't pretty . > (PyInt_FromString is also not described, but PyLong_FromString is. > Is the former deprecated?) Sounds like the lack of docs is just a bug. From greg@users.sourceforge.net Mon Feb 3 04:19:43 2003 From: greg@users.sourceforge.net (greg@users.sourceforge.net) Date: Sun, 02 Feb 2003 20:19:43 -0800 Subject: [Python-checkins] python/dist/src/Lib/bsddb/test test_misc.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/bsddb/test In directory sc8-pr-cvs1:/tmp/cvs-serv19167/bsddb/test Modified Files: test_misc.py Log Message: fix for use on python 2.1 Index: test_misc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_misc.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_misc.py 28 Jan 2003 17:20:44 -0000 1.3 --- test_misc.py 3 Feb 2003 04:19:40 -0000 1.4 *************** *** 13,18 **** from bsddb3 import db, dbshelve - from test.test_support import verbose - #---------------------------------------------------------------------- --- 13,16 ---- From greg@users.sourceforge.net Mon Feb 3 04:28:28 2003 From: greg@users.sourceforge.net (greg@users.sourceforge.net) Date: Sun, 02 Feb 2003 20:28:28 -0800 Subject: [Python-checkins] python/dist/src/Modules _bsddb.c,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv21215/extsrc Modified Files: _bsddb.c Log Message: version 4.1.4 (4.1.3 just released) Index: _bsddb.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_bsddb.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** _bsddb.c 28 Jan 2003 17:30:46 -0000 1.7 --- _bsddb.c 3 Feb 2003 04:28:26 -0000 1.8 *************** *** 86,90 **** #define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR) ! #define PY_BSDDB_VERSION "4.1.3" static char *rcs_id = "$Id$"; --- 86,90 ---- #define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR) ! #define PY_BSDDB_VERSION "4.1.4" static char *rcs_id = "$Id$"; From montanaro@users.sourceforge.net Mon Feb 3 05:13:26 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 21:13:26 -0800 Subject: [Python-checkins] python/dist/src/Doc/api concrete.tex,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory sc8-pr-cvs1:/tmp/cvs-serv32146 Modified Files: concrete.tex Log Message: * Add description of PyInt_FromString. * Correct description of PyFloat_FromString. While ignored, the pend argument still has to be given. * Typo in PyLong_FromString. Index: concrete.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/concrete.tex,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** concrete.tex 3 Feb 2003 03:56:36 -0000 1.19 --- concrete.tex 3 Feb 2003 05:13:24 -0000 1.20 *************** *** 130,133 **** --- 130,152 ---- \end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyInt_FromString}{char *str, char **pend, + int base} + Return a new \ctype{PyIntObject} or \ctype{PyLongObject} based on the + string value in \var{str}, which is interpreted according to the radix in + \var{base}. If \var{pend} is non-\NULL, \code{*\var{pend}} will point to + the first character in \var{str} which follows the representation of the + number. If \var{base} is \code{0}, the radix will be determined based on + the leading characters of \var{str}: if \var{str} starts with \code{'0x'} + or \code{'0X'}, radix 16 will be used; if \var{str} starts with + \code{'0'}, radix 8 will be used; otherwise radix 10 will be used. If + \var{base} is not \code{0}, it must be between \code{2} and \code{36}, + inclusive. Leading spaces are ignored. If there are no digits, + \exception{ValueError} will be raised. If the string represents a number + too large to be contained within the machine's \ctype{long int} type and + overflow warnings are being suppressed, a \ctype{PyLongObject} will be + returned. If overflow warnings are not being suppressed, \NULL{} will be + returned in this case. + \end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyInt_FromLong}{long ival} Creates a new integer object with a value of \var{ival}. *************** *** 215,219 **** point to the first character in \var{str} which follows the representation of the number. If \var{base} is \code{0}, the radix ! will be determined base on the leading characters of \var{str}: if \var{str} starts with \code{'0x'} or \code{'0X'}, radix 16 will be used; if \var{str} starts with \code{'0'}, radix 8 will be used; --- 234,238 ---- point to the first character in \var{str} which follows the representation of the number. If \var{base} is \code{0}, the radix ! will be determined based on the leading characters of \var{str}: if \var{str} starts with \code{'0x'} or \code{'0X'}, radix 16 will be used; if \var{str} starts with \code{'0'}, radix 8 will be used; *************** *** 318,324 **** \end{cfuncdesc} ! \begin{cfuncdesc}{PyObject*}{PyFloat_FromString}{PyObject *str} Creates a \ctype{PyFloatObject} object based on the string value in ! \var{str}, or \NULL{} on failure. \end{cfuncdesc} --- 337,344 ---- \end{cfuncdesc} ! \begin{cfuncdesc}{PyObject*}{PyFloat_FromString}{PyObject *str, char **pend} Creates a \ctype{PyFloatObject} object based on the string value in ! \var{str}, or \NULL{} on failure. The \var{pend} argument is ignored. It ! remains only for backward compatibility. \end{cfuncdesc} From andrewmcnamara@users.sourceforge.net Mon Feb 3 05:32:21 2003 From: andrewmcnamara@users.sourceforge.net (andrewmcnamara@users.sourceforge.net) Date: Sun, 02 Feb 2003 21:32:21 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.16,1.17 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv4371 Modified Files: csv.py Log Message: Renamed CSVError back to Error, renamed writer methods as writerow and writerows. Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** csv.py 3 Feb 2003 02:55:19 -0000 1.16 --- csv.py 3 Feb 2003 05:32:19 -0000 1.17 *************** *** 1,7 **** import _csv ! from _csv import Error as CSVError __all__ = [ "QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", ! "CSVError", "Dialect", "excel", "excel_tab", "reader", "writer", "register_dialect", "get_dialect", "list_dialects"] --- 1,7 ---- import _csv ! from _csv import Error __all__ = [ "QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", ! "Error", "Dialect", "excel", "excel_tab", "reader", "writer", "register_dialect", "get_dialect", "list_dialects"] *************** *** 36,40 **** dialect_obj = _dialects[dialect] except KeyError: ! raise CSVError('Unknown dialect') parser_options = {} for attr in dir(dialect_obj): --- 36,40 ---- dialect_obj = _dialects[dialect] except KeyError: ! raise Error('Unknown dialect') parser_options = {} for attr in dir(dialect_obj): *************** *** 65,69 **** _OCcsv.__init__(self, dialect, **options) ! def write(self, fields): # if fields is a dict, we need a valid fieldnames list # if self.fieldnames is None we'll get a TypeError in the for stmt --- 65,69 ---- _OCcsv.__init__(self, dialect, **options) ! def writerow(self, fields): # if fields is a dict, we need a valid fieldnames list # if self.fieldnames is None we'll get a TypeError in the for stmt *************** *** 78,95 **** self.fileobj.write(self.parser.join(fields)) ! def writelines(self, lines): for fields in lines: self.write(fields) - - def close(self): - self.fileobj.close() - del self.fileobj - - def __del__(self): - if hasattr(self, 'fileobj'): - try: - self.close() - except: - pass def register_dialect(name, dialect): --- 78,84 ---- self.fileobj.write(self.parser.join(fields)) ! def writerows(self, lines): for fields in lines: self.write(fields) def register_dialect(name, dialect): From montanaro@users.sourceforge.net Mon Feb 3 06:21:09 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 22:21:09 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv libcsv.tex,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv16625 Modified Files: libcsv.tex Log Message: tracking write()/writelines()/CSVError to writerow()/writerows()/Error. Index: libcsv.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/libcsv.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** libcsv.tex 3 Feb 2003 03:09:28 -0000 1.1 --- libcsv.tex 3 Feb 2003 06:21:07 -0000 1.2 *************** *** 23,26 **** --- 23,27 ---- CSV formats. + \subsection{Relationship to other Python modules} *************** *** 80,83 **** --- 81,90 ---- \end{funcdesc} + The \module{csv} module defines the following exception. + + \begin{excdesc}{Error} + Raised by any of the functions when an error is detected. + \end{excdesc} + The \module{csv} module defines the following constants. *************** *** 103,106 **** --- 110,114 ---- \end{datadesc} + \subsection{Dialects and Formatting Parameters\label{fmt-params}} *************** *** 114,117 **** --- 122,126 ---- individual formatting parameters, described in the following section. + \subsubsection{Formatting Parameters} *************** *** 159,162 **** --- 168,172 ---- \end{description} + \subsection{Reader Objects} *************** *** 168,188 **** \end{methoddesc} \subsection{Writer Objects} \class{Writer} objects have the following public methods. ! \begin{methoddesc}{write}{row} Write the \var{row} parameter to the writer's file object, formatted according to the current dialect. \end{methoddesc} ! \begin{methoddesc}{writelines}{rows} Write all the \var{rows} parameters to the writer's file object, formatted according to the current dialect. \end{methoddesc} - \begin{methoddesc}{close}{} - Close the underlying file object. - \end{methoddesc} \subsection{Examples} --- 178,196 ---- \end{methoddesc} + \subsection{Writer Objects} \class{Writer} objects have the following public methods. ! \begin{methoddesc}{writerow}{row} Write the \var{row} parameter to the writer's file object, formatted according to the current dialect. \end{methoddesc} ! \begin{methoddesc}{writerows}{rows} Write all the \var{rows} parameters to the writer's file object, formatted according to the current dialect. \end{methoddesc} \subsection{Examples} *************** *** 201,205 **** writer = csv.writer(file("some.csv", "w")) for row in someiterable: ! writer.write(row) \end{verbatim} --- 209,213 ---- writer = csv.writer(file("some.csv", "w")) for row in someiterable: ! writer.writerow(row) \end{verbatim} From montanaro@users.sourceforge.net Mon Feb 3 06:25:32 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 22:25:32 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv libcsv.tex,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv17557 Modified Files: libcsv.tex Log Message: add a couple cross-references Index: libcsv.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/libcsv.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** libcsv.tex 3 Feb 2003 06:21:07 -0000 1.2 --- libcsv.tex 3 Feb 2003 06:25:30 -0000 1.3 *************** *** 216,217 **** --- 216,221 ---- or output file. + \begin{seealso} + \seemodule{array}{Arrays of uniformly types numeric values.} + \seepep{305}{CSV File API} + \end{seealso} From montanaro@users.sourceforge.net Mon Feb 3 06:34:25 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 22:34:25 -0800 Subject: [Python-checkins] python/dist/src/Tools/scripts trace.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv19536 Modified Files: trace.py Log Message: add missing "summary" from long options list Index: trace.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/trace.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** trace.py 11 Dec 2002 21:43:13 -0000 1.12 --- trace.py 3 Feb 2003 06:34:22 -0000 1.13 *************** *** 598,602 **** opts, prog_argv = getopt.getopt(argv[1:], "tcrRf:d:msC:l", ["help", "version", "trace", "count", ! "report", "no-report", "file=", "missing", "ignore-module=", "ignore-dir=", --- 598,602 ---- opts, prog_argv = getopt.getopt(argv[1:], "tcrRf:d:msC:l", ["help", "version", "trace", "count", ! "report", "no-report", "summary", "file=", "missing", "ignore-module=", "ignore-dir=", From montanaro@users.sourceforge.net Mon Feb 3 06:44:15 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 22:44:15 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv21699 Modified Files: csv.py Log Message: in writer.writerows, self.write() -> self.writerow() Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** csv.py 3 Feb 2003 05:32:19 -0000 1.17 --- csv.py 3 Feb 2003 06:44:13 -0000 1.18 *************** *** 80,84 **** def writerows(self, lines): for fields in lines: ! self.write(fields) def register_dialect(name, dialect): --- 80,84 ---- def writerows(self, lines): for fields in lines: ! self.writerow(fields) def register_dialect(name, dialect): From montanaro@users.sourceforge.net Mon Feb 3 06:46:02 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Sun, 02 Feb 2003 22:46:02 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv22046 Modified Files: test_csv.py Log Message: write()/writelines()/CSVError -> writerow()/writerows()/Error added simple test passing Dialect instance instead of string Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_csv.py 3 Feb 2003 02:56:20 -0000 1.9 --- test_csv.py 3 Feb 2003 06:45:59 -0000 1.10 *************** *** 16,20 **** fileobj = StringIO() writer = csv.writer(fileobj, dialect = self.dialect) ! writer.writelines(input) self.assertEqual(fileobj.getvalue(), expected_result) --- 16,20 ---- fileobj = StringIO() writer = csv.writer(fileobj, dialect = self.dialect) ! writer.writerows(input) self.assertEqual(fileobj.getvalue(), expected_result) *************** *** 117,121 **** writer = csv.writer(fileobj, dialect="excel", fieldnames = ["f1", "f2", "f3"]) ! writer.write({"f1": 10, "f3": "abc"}) self.assertEqual(fileobj.getvalue(), "10,,abc\r\n") --- 117,121 ---- writer = csv.writer(fileobj, dialect="excel", fieldnames = ["f1", "f2", "f3"]) ! writer.writerow({"f1": 10, "f3": "abc"}) self.assertEqual(fileobj.getvalue(), "10,,abc\r\n") *************** *** 123,127 **** fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") ! self.assertRaises(csv.CSVError, writer.write, {"f1": 10, "f3": "abc"}) class TestArrayWrites(unittest.TestCase): --- 123,127 ---- fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") ! self.assertRaises(csv.Error, writer.writerow, {"f1": 10, "f3": "abc"}) class TestArrayWrites(unittest.TestCase): *************** *** 132,136 **** fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") ! writer.write(a) expected = ",".join([str(i) for i in a])+"\r\n" self.assertEqual(fileobj.getvalue(), expected) --- 132,136 ---- fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") ! writer.writerow(a) expected = ",".join([str(i) for i in a])+"\r\n" self.assertEqual(fileobj.getvalue(), expected) *************** *** 142,146 **** fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") ! writer.write(a) expected = ",".join([str(i) for i in a])+"\r\n" self.assertEqual(fileobj.getvalue(), expected) --- 142,146 ---- fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") ! writer.writerow(a) expected = ",".join([str(i) for i in a])+"\r\n" self.assertEqual(fileobj.getvalue(), expected) *************** *** 152,156 **** fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") ! writer.write(a) expected = ",".join([str(i) for i in a])+"\r\n" self.assertEqual(fileobj.getvalue(), expected) --- 152,156 ---- fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") ! writer.writerow(a) expected = ",".join([str(i) for i in a])+"\r\n" self.assertEqual(fileobj.getvalue(), expected) *************** *** 161,165 **** fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") ! writer.write(a) expected = ",".join(a)+"\r\n" self.assertEqual(fileobj.getvalue(), expected) --- 161,165 ---- fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") ! writer.writerow(a) expected = ",".join(a)+"\r\n" self.assertEqual(fileobj.getvalue(), expected) *************** *** 184,187 **** --- 184,196 ---- "myexceltsv", myexceltsv) + def test_dialect_class(self): + class myexceltsv(csv.Dialect): + delimiter = "\t" + fileobj = StringIO() + writer = csv.writer(fileobj, dialect=myexceltsv()) + writer.writerow([1,2,3]) + self.assertEqual(fileobj.getvalue(), "1\t2\t3\r\n") + + def _testclasses(): mod = sys.modules[__name__] From mwh@users.sourceforge.net Mon Feb 3 11:04:29 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Mon, 03 Feb 2003 03:04:29 -0800 Subject: [Python-checkins] python/dist/src/Lib cmd.py,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv4243/Lib Modified Files: cmd.py Log Message: Fix bug [ 676342 ] after using pdb readline does not work correctly using Michael Stone's patch so the completer functionality of cmd is only setup between preloop and postloop. Index: cmd.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/cmd.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** cmd.py 13 Jan 2003 21:18:54 -0000 1.33 --- cmd.py 3 Feb 2003 11:04:27 -0000 1.34 *************** *** 87,97 **** """ self.cmdqueue = [] ! if completekey: ! try: ! import readline ! readline.set_completer(self.complete) ! readline.parse_and_bind(completekey+": complete") ! except ImportError: ! pass def cmdloop(self, intro=None): --- 87,91 ---- """ self.cmdqueue = [] ! self.completekey = completekey def cmdloop(self, intro=None): *************** *** 143,147 **** def preloop(self): """Hook method executed once when the cmdloop() method is called.""" ! pass def postloop(self): --- 137,148 ---- def preloop(self): """Hook method executed once when the cmdloop() method is called.""" ! if self.completekey: ! try: ! import readline ! self.old_completer = readline.get_completer() ! readline.set_completer(self.complete) ! readline.parse_and_bind(self.completekey+": complete") ! except ImportError: ! pass def postloop(self): *************** *** 150,154 **** """ ! pass def parseline(self, line): --- 151,160 ---- """ ! if self.completekey: ! try: ! import readline ! readline.set_completer(self.old_completer) ! except ImportError: ! pass def parseline(self, line): From jvr@users.sourceforge.net Mon Feb 3 11:43:56 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Mon, 03 Feb 2003 03:43:56 -0800 Subject: [Python-checkins] python/dist/src/Lib/distutils/command config.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils/command In directory sc8-pr-cvs1:/tmp/cvs-serv28776 Modified Files: config.py Log Message: patch #664131, fix config command on OSX and Linux Index: config.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/command/config.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** config.py 19 Nov 2002 13:12:28 -0000 1.15 --- config.py 3 Feb 2003 11:43:54 -0000 1.16 *************** *** 152,156 **** target_lang=lang) ! prog = prog + self.compiler.exe_extension self.temp_files.append(prog) --- 152,157 ---- target_lang=lang) ! if self.compiler.exe_extension is not None: ! prog = prog + self.compiler.exe_extension self.temp_files.append(prog) From doerwalter@users.sourceforge.net Mon Feb 3 11:54:42 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Mon, 03 Feb 2003 03:54:42 -0800 Subject: [Python-checkins] python/dist/src/Lib/test regrtest.py,1.120,1.121 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv425/Lib/test Modified Files: regrtest.py Log Message: Remove test_b1 and test_b2 from the list of tests that are no real tests, because test_b1 and test_b2 no longer exist. (Spotted by Raymond Hettinger) Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.120 retrieving revision 1.121 diff -C2 -d -r1.120 -r1.121 *** regrtest.py 29 Jan 2003 16:24:16 -0000 1.120 --- regrtest.py 3 Feb 2003 11:54:39 -0000 1.121 *************** *** 339,344 **** NOTTESTS = [ 'test_support', - 'test_b1', - 'test_b2', 'test_future1', 'test_future2', --- 339,342 ---- From gward@users.sourceforge.net Mon Feb 3 14:47:01 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Mon, 03 Feb 2003 06:47:01 -0800 Subject: [Python-checkins] python/dist/src/Lib textwrap.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv1030/Lib Modified Files: textwrap.py Log Message: Add __all__ (suggested by Raymond Hettinger). Rename 'whitespace' global to '_whitespace' -- it's not part of the public interface. Index: textwrap.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/textwrap.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** textwrap.py 12 Dec 2002 17:24:35 -0000 1.22 --- textwrap.py 3 Feb 2003 14:46:57 -0000 1.23 *************** *** 13,16 **** --- 13,18 ---- import string, re + __all__ = ['TextWrapper', 'wrap', 'fill'] + # Hardcode the recognized whitespace characters to the US-ASCII # whitespace characters. The main reason for doing this is that in *************** *** 21,25 **** # *non-breaking* space), 2) possibly cause problems with Unicode, # since 0xa0 is not in range(128). ! whitespace = '\t\n\x0b\x0c\r ' class TextWrapper: --- 23,27 ---- # *non-breaking* space), 2) possibly cause problems with Unicode, # since 0xa0 is not in range(128). ! _whitespace = '\t\n\x0b\x0c\r ' class TextWrapper: *************** *** 59,67 **** """ ! whitespace_trans = string.maketrans(whitespace, ' ' * len(whitespace)) unicode_whitespace_trans = {} uspace = ord(u' ') ! for x in map(ord, whitespace): unicode_whitespace_trans[x] = uspace --- 61,69 ---- """ ! whitespace_trans = string.maketrans(_whitespace, ' ' * len(_whitespace)) unicode_whitespace_trans = {} uspace = ord(u' ') ! for x in map(ord, _whitespace): unicode_whitespace_trans[x] = uspace From montanaro@users.sourceforge.net Mon Feb 3 15:08:44 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 03 Feb 2003 07:08:44 -0800 Subject: [Python-checkins] python/dist/src/Tools/scripts pickle2db.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv12298 Added Files: pickle2db.py Log Message: convert pickles generated by db2pickle.py back to database files --- NEW FILE: pickle2db.py --- #!/usr/bin/env python """ Synopsis: %(prog)s [-h|-b|-r|-a|-d] dbfile [ picklefile ] Read the given picklefile as a series of key/value pairs and write to a new bsddb database. If the database already exists, any contents are deleted. The optional flags indicate the type of the database (bsddb hash, bsddb btree, bsddb recno, anydbm, dbm). The default is hash. If a pickle file is named it is opened for read access. If no pickle file is named, the pickle input is read from standard input. Note that recno databases can only contain numeric keys, so you can't dump a hash or btree database using bsddb2pickle.py and reconstitute it to a recno database with %(prog)s. """ import getopt try: import bsddb except ImportError: bsddb = None try: import dbm except ImportError: dbm = None try: import anydbm except ImportError: anydbm = None import sys try: import cPickle as pickle except ImportError: import pickle prog = sys.argv[0] def usage(): print >> sys.stderr, __doc__ % globals() def main(args): try: opts, args = getopt.getopt(args, "hbrda", ["hash", "btree", "recno", "dbm", "anydbm"]) except getopt.error: usage() return 1 if len(args) == 0 or len(args) > 2: usage() return 1 elif len(args) == 1: dbfile = args[0] pfile = sys.stdin else: dbfile = args[0] try: pfile = file(args[1], 'rb') except IOError: print >> sys.stderr, "Unable to open", args[1] return 1 dbopen = None for opt, arg in opts: if opt in ("-h", "--hash"): try: dbopen = bsddb.hashopen except AttributeError: print >> sys.stderr, "bsddb module unavailable." return 1 elif opt in ("-b", "--btree"): try: dbopen = bsddb.btopen except AttributeError: print >> sys.stderr, "bsddb module unavailable." return 1 elif opt in ("-r", "--recno"): try: dbopen = bsddb.rnopen except AttributeError: print >> sys.stderr, "bsddb module unavailable." return 1 elif opt in ("-a", "--anydbm"): try: dbopen = anydbm.open except AttributeError: print >> sys.stderr, "anydbm module unavailable." return 1 elif opt in ("-d", "--dbm"): try: dbopen = dbm.open except AttributeError: print >> sys.stderr, "dbm module unavailable." return 1 if dbopen is None: if bsddb is None: print >> sys.stderr, "bsddb module unavailable -" print >> sys.stderr, "must specify dbtype." return 1 else: dbopen = bsddb.hashopen try: db = dbopen(dbfile, 'c') except bsddb.error: print >> sys.stderr, "Unable to open", dbfile, print >> sys.stderr, "Check for format or version mismatch." return 1 else: for k in db.keys(): del db[k] while 1: try: (key, val) = pickle.load(pfile) except EOFError: break db[key] = val db.close() pfile.close() return 0 if __name__ == "__main__": sys.exit(main(sys.argv[1:])) From montanaro@users.sourceforge.net Mon Feb 3 15:09:06 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 03 Feb 2003 07:09:06 -0800 Subject: [Python-checkins] python/dist/src/Tools/scripts db2pickle.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv12456 Added Files: db2pickle.py Log Message: dump database files to pickle format --- NEW FILE: db2pickle.py --- #!/usr/bin/env python """ Synopsis: %(prog)s [-h|-b|-r] dbfile [ picklefile ] Convert the bsddb database file given on the command like to a pickle representation. The optional flags indicate the type of the database (hash, btree, recno). The default is hash. If a pickle file is named it is opened for write access (deleting any existing data). If no pickle file is named, the pickle output is written to standard output. """ import getopt try: import bsddb except ImportError: bsddb = None try: import dbm except ImportError: dbm = None try: import anydbm except ImportError: anydbm = None import sys try: import cPickle as pickle except ImportError: import pickle prog = sys.argv[0] def usage(): print >> sys.stderr, __doc__ % globals() def main(args): try: opts, args = getopt.getopt(args, "hbrda", ["hash", "btree", "recno", "dbm", "anydbm"]) except getopt.error: usage() return 1 if len(args) == 0 or len(args) > 2: usage() return 1 elif len(args) == 1: dbfile = args[0] pfile = sys.stdout else: dbfile = args[0] try: pfile = file(args[1], 'wb') except IOError: print >> sys.stderr, "Unable to open", args[1] return 1 dbopen = None for opt, arg in opts: if opt in ("-h", "--hash"): try: dbopen = bsddb.hashopen except AttributeError: print >> sys.stderr, "bsddb module unavailable." return 1 elif opt in ("-b", "--btree"): try: dbopen = bsddb.btopen except AttributeError: print >> sys.stderr, "bsddb module unavailable." return 1 elif opt in ("-r", "--recno"): try: dbopen = bsddb.rnopen except AttributeError: print >> sys.stderr, "bsddb module unavailable." return 1 elif opt in ("-a", "--anydbm"): try: dbopen = anydbm.open except AttributeError: print >> sys.stderr, "anydbm module unavailable." return 1 elif opt in ("-d", "--dbm"): try: dbopen = dbm.open except AttributeError: print >> sys.stderr, "dbm module unavailable." return 1 if dbopen is None: if bsddb is None: print >> sys.stderr, "bsddb module unavailable -" print >> sys.stderr, "must specify dbtype." return 1 else: dbopen = bsddb.hashopen try: db = dbopen(dbfile, 'r') except bsddb.error: print >> sys.stderr, "Unable to open", dbfile, print >> sys.stderr, "Check for format or version mismatch." return 1 for k in db.keys(): pickle.dump((k, db[k]), pfile, 1==1) db.close() pfile.close() return 0 if __name__ == "__main__": sys.exit(main(sys.argv[1:])) From montanaro@users.sourceforge.net Mon Feb 3 15:09:35 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 03 Feb 2003 07:09:35 -0800 Subject: [Python-checkins] python/dist/src/Tools/scripts README,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv12663 Modified Files: README Log Message: note db2pickle.py and pickle2db.py Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/README,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** README 2 Jan 2003 02:24:22 -0000 1.9 --- README 3 Feb 2003 15:09:32 -0000 1.10 *************** *** 12,15 **** --- 12,16 ---- crlf.py Change CRLF line endings to LF (Windows to Unix) cvsfiles.py Print a list of files that are under CVS + db2pickle.py Dump a database file to a pickle dutree.py Format du(1) output as a tree sorted by size eptags.py Create Emacs TAGS file for Python modules *************** *** 35,38 **** --- 36,40 ---- pathfix.py Change #!/usr/local/bin/python into something else pdeps.py Print dependencies between Python modules + pickle2db.py Load a pickle generated by db2pickle.py to a database pindent.py Indent Python code, giving block-closing comments ptags.py Create vi tags file for Python modules From akuchling@users.sourceforge.net Mon Feb 3 15:16:20 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Mon, 03 Feb 2003 07:16:20 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.111,1.112 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv15634 Modified Files: whatsnew23.tex Log Message: [Bug #679251] Use correct constant name Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.111 retrieving revision 1.112 diff -C2 -d -r1.111 -r1.112 *** whatsnew23.tex 27 Jan 2003 16:36:34 -0000 1.111 --- whatsnew23.tex 3 Feb 2003 15:16:15 -0000 1.112 *************** *** 328,332 **** cause a \exception{UnicodeError} to be raised. Applications can test whether arbitrary Unicode strings are supported as file names by ! checking \member{os.path.unicode_file_names}, a Boolean value. \begin{seealso} --- 328,332 ---- cause a \exception{UnicodeError} to be raised. Applications can test whether arbitrary Unicode strings are supported as file names by ! checking \member{os.path.supports_unicode_filenames}, a Boolean value. \begin{seealso} *************** *** 2107,2115 **** The author would like to thank the following people for offering suggestions, corrections and assistance with various drafts of this ! article: Simon Brunning, Michael Chermside, Scott David Daniels, ! Fred~L. Drake, Jr., Kelly Gerber, Raymond Hettinger, Michael Hudson, ! Detlef Lannert, Martin von L\"owis, Andrew MacIntyre, Lalo Martins, ! Gustavo Niemeyer, Neal Norwitz, Hans Nowak, Chris Reedy, Vinay Sajip, ! Neil Schemenauer, Jason Tishler, Just van~Rossum. \end{document} --- 2107,2115 ---- The author would like to thank the following people for offering suggestions, corrections and assistance with various drafts of this ! article: Simon Brunning, Michael Chermside, Andrew Dalke, Scott David ! Daniels, Fred~L. Drake, Jr., Kelly Gerber, Raymond Hettinger, Michael ! Hudson, Detlef Lannert, Martin von L\"owis, Andrew MacIntyre, Lalo ! Martins, Gustavo Niemeyer, Neal Norwitz, Hans Nowak, Chris Reedy, ! Vinay Sajip, Neil Schemenauer, Jason Tishler, Just van~Rossum. \end{document} From fdrake@users.sourceforge.net Mon Feb 3 15:19:36 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Mon, 03 Feb 2003 07:19:36 -0800 Subject: [Python-checkins] python/dist/src/Lib/test regrtest.py,1.121,1.122 test_support.py,1.47,1.48 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv17119 Modified Files: regrtest.py test_support.py Log Message: test_support.requires(): Instead of raising TestSkipped, raise a new exception, ResourceDenied. This is used to distinguish between tests that are skipped for other reasons (platform support, missing data, etc.) from those that are skipped because a "resource" has not been enabled. This prevents those tests from being reported as unexpected skips for the platform; those should only be considered unexpected skips if the resource were enabled. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.121 retrieving revision 1.122 diff -C2 -d -r1.121 -r1.122 *** regrtest.py 3 Feb 2003 11:54:39 -0000 1.121 --- regrtest.py 3 Feb 2003 15:19:27 -0000 1.122 *************** *** 197,200 **** --- 197,201 ---- bad = [] skipped = [] + resource_denieds = [] if findleaks: *************** *** 264,267 **** --- 265,270 ---- else: skipped.append(test) + if ok == -2: + resource_denieds.append(test) if findleaks: gc.collect() *************** *** 300,304 **** plat = sys.platform if e.isvalid(): ! surprise = Set(skipped) - e.getexpected() if surprise: print count(len(surprise), "skip"), \ --- 303,307 ---- plat = sys.platform if e.isvalid(): ! surprise = Set(skipped) - e.getexpected() - Set(resource_denieds) if surprise: print count(len(surprise), "skip"), \ *************** *** 396,399 **** --- 399,407 ---- finally: sys.stdout = save_stdout + except test_support.ResourceDenied, msg: + if not quiet: + print test, "skipped --", msg + sys.stdout.flush() + return -2 except (ImportError, test_support.TestSkipped), msg: if not quiet: Index: test_support.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_support.py,v retrieving revision 1.47 retrieving revision 1.48 diff -C2 -d -r1.47 -r1.48 *** test_support.py 4 Dec 2002 03:26:57 -0000 1.47 --- test_support.py 3 Feb 2003 15:19:30 -0000 1.48 *************** *** 22,25 **** --- 22,33 ---- """ + class ResourceDenied(TestSkipped): + """Test skipped because it requested a disallowed resource. + + This is raised when a test calls requires() for a resource that + has not be enabled. It is used to distinguish between expected + and unexpected skips. + """ + verbose = 1 # Flag set to 0 by regrtest.py use_resources = None # Flag set to [] by regrtest.py *************** *** 58,62 **** if msg is None: msg = "Use of the `%s' resource not enabled" % resource ! raise TestSkipped(msg) FUZZ = 1e-6 --- 66,70 ---- if msg is None: msg = "Use of the `%s' resource not enabled" % resource ! raise ResourceDenied(msg) FUZZ = 1e-6 From akuchling@users.sourceforge.net Mon Feb 3 15:21:19 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Mon, 03 Feb 2003 07:21:19 -0800 Subject: [Python-checkins] python/dist/src/Lib BaseHTTPServer.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv18099 Modified Files: BaseHTTPServer.py Log Message: Bug #676273: Rewrite paragraph in module docstring Index: BaseHTTPServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/BaseHTTPServer.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** BaseHTTPServer.py 31 May 2002 23:03:33 -0000 1.22 --- BaseHTTPServer.py 3 Feb 2003 15:21:15 -0000 1.23 *************** *** 133,141 **** the ASCII character with hex code xx). ! The protocol is vague about whether lines are separated by LF ! characters or by CRLF pairs -- for compatibility with the widest ! range of clients, both should be accepted. Similarly, whitespace ! in the request line should be treated sensibly (allowing multiple ! spaces between components and allowing trailing whitespace). Similarly, for output, lines ought to be separated by CRLF pairs --- 133,141 ---- the ASCII character with hex code xx). ! The specification specifies that lines are separated by CRLF but ! for compatibility with the widest range of clients recommends ! servers also handle LF. Similarly, whitespace in the request line ! is treated sensibly (allowing multiple spaces between components ! and allowing trailing whitespace). Similarly, for output, lines ought to be separated by CRLF pairs From gvanrossum@users.sourceforge.net Mon Feb 3 15:25:08 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 03 Feb 2003 07:25:08 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_long.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv19986 Modified Files: test_long.py Log Message: test_float_overflow(): make shuge (added last week) a little less huge. On older Linux systems, the C library's strtod() apparently gives up before seeing the end of the string when it sees so many digits that it thinks the result must be Infinity. (It is wrong, BTW -- there could be an "e-10000" hiding behind 10,000 digits.) The shorter shuge still tests what it's testing, without relying on strtod() doing a super job. Index: test_long.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_long.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** test_long.py 28 Jan 2003 19:21:19 -0000 1.22 --- test_long.py 3 Feb 2003 15:25:01 -0000 1.23 *************** *** 372,376 **** verify(float(long(x)) == x) ! shuge = '12345' * 1000 huge = 1L << 30000 mhuge = -huge --- 372,376 ---- verify(float(long(x)) == x) ! shuge = '12345' * 120 huge = 1L << 30000 mhuge = -huge From montanaro@users.sourceforge.net Mon Feb 3 15:28:26 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 03 Feb 2003 07:28:26 -0800 Subject: [Python-checkins] python/dist/src/Tools/scripts pickle2db.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv21767 Modified Files: pickle2db.py Log Message: try to avoid gross incompatibilities with earlier versions of Python Index: pickle2db.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/pickle2db.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pickle2db.py 3 Feb 2003 15:08:42 -0000 1.1 --- pickle2db.py 3 Feb 2003 15:28:23 -0000 1.2 *************** *** 38,42 **** def usage(): ! print >> sys.stderr, __doc__ % globals() def main(args): --- 38,42 ---- def usage(): ! sys.stderr.write(__doc__ % globals()) def main(args): *************** *** 57,63 **** dbfile = args[0] try: ! pfile = file(args[1], 'rb') except IOError: ! print >> sys.stderr, "Unable to open", args[1] return 1 --- 57,63 ---- dbfile = args[0] try: ! pfile = open(args[1], 'rb') except IOError: ! sys.stderr.write("Unable to open %s\n" % args[1]) return 1 *************** *** 68,72 **** dbopen = bsddb.hashopen except AttributeError: ! print >> sys.stderr, "bsddb module unavailable." return 1 elif opt in ("-b", "--btree"): --- 68,72 ---- dbopen = bsddb.hashopen except AttributeError: ! sys.stderr.write("bsddb module unavailable.\n") return 1 elif opt in ("-b", "--btree"): *************** *** 74,78 **** dbopen = bsddb.btopen except AttributeError: ! print >> sys.stderr, "bsddb module unavailable." return 1 elif opt in ("-r", "--recno"): --- 74,78 ---- dbopen = bsddb.btopen except AttributeError: ! sys.stderr.write("bsddb module unavailable.\n") return 1 elif opt in ("-r", "--recno"): *************** *** 80,84 **** dbopen = bsddb.rnopen except AttributeError: ! print >> sys.stderr, "bsddb module unavailable." return 1 elif opt in ("-a", "--anydbm"): --- 80,84 ---- dbopen = bsddb.rnopen except AttributeError: ! sys.stderr.write("bsddb module unavailable.\n") return 1 elif opt in ("-a", "--anydbm"): *************** *** 86,90 **** dbopen = anydbm.open except AttributeError: ! print >> sys.stderr, "anydbm module unavailable." return 1 elif opt in ("-d", "--dbm"): --- 86,90 ---- dbopen = anydbm.open except AttributeError: ! sys.stderr.write("anydbm module unavailable.\n") return 1 elif opt in ("-d", "--dbm"): *************** *** 92,101 **** dbopen = dbm.open except AttributeError: ! print >> sys.stderr, "dbm module unavailable." return 1 if dbopen is None: if bsddb is None: ! print >> sys.stderr, "bsddb module unavailable -" ! print >> sys.stderr, "must specify dbtype." return 1 else: --- 92,101 ---- dbopen = dbm.open except AttributeError: ! sys.stderr.write("dbm module unavailable.\n") return 1 if dbopen is None: if bsddb is None: ! sys.stderr.write("bsddb module unavailable - ") ! sys.stderr.write("must specify dbtype.\n") return 1 else: *************** *** 105,110 **** db = dbopen(dbfile, 'c') except bsddb.error: ! print >> sys.stderr, "Unable to open", dbfile, ! print >> sys.stderr, "Check for format or version mismatch." return 1 else: --- 105,110 ---- db = dbopen(dbfile, 'c') except bsddb.error: ! sys.stderr.write("Unable to open %s. " % dbfile) ! sys.stderr.write("Check for format or version mismatch.\n") return 1 else: From montanaro@users.sourceforge.net Mon Feb 3 15:29:37 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 03 Feb 2003 07:29:37 -0800 Subject: [Python-checkins] python/dist/src/Tools/scripts db2pickle.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv22246 Modified Files: db2pickle.py Log Message: try to avoid gross incompatibilities with older versions of Python Index: db2pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/db2pickle.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** db2pickle.py 3 Feb 2003 15:09:03 -0000 1.1 --- db2pickle.py 3 Feb 2003 15:29:34 -0000 1.2 *************** *** 34,38 **** def usage(): ! print >> sys.stderr, __doc__ % globals() def main(args): --- 34,38 ---- def usage(): ! sys.stderr.write(__doc__ % globals()) def main(args): *************** *** 53,59 **** dbfile = args[0] try: ! pfile = file(args[1], 'wb') except IOError: ! print >> sys.stderr, "Unable to open", args[1] return 1 --- 53,59 ---- dbfile = args[0] try: ! pfile = open(args[1], 'wb') except IOError: ! sys.stderr.write("Unable to open %s\n" % args[1]) return 1 *************** *** 64,68 **** dbopen = bsddb.hashopen except AttributeError: ! print >> sys.stderr, "bsddb module unavailable." return 1 elif opt in ("-b", "--btree"): --- 64,68 ---- dbopen = bsddb.hashopen except AttributeError: ! sys.stderr.write("bsddb module unavailable.\n") return 1 elif opt in ("-b", "--btree"): *************** *** 70,74 **** dbopen = bsddb.btopen except AttributeError: ! print >> sys.stderr, "bsddb module unavailable." return 1 elif opt in ("-r", "--recno"): --- 70,74 ---- dbopen = bsddb.btopen except AttributeError: ! sys.stderr.write("bsddb module unavailable.\n") return 1 elif opt in ("-r", "--recno"): *************** *** 76,80 **** dbopen = bsddb.rnopen except AttributeError: ! print >> sys.stderr, "bsddb module unavailable." return 1 elif opt in ("-a", "--anydbm"): --- 76,80 ---- dbopen = bsddb.rnopen except AttributeError: ! sys.stderr.write("bsddb module unavailable.\n") return 1 elif opt in ("-a", "--anydbm"): *************** *** 82,86 **** dbopen = anydbm.open except AttributeError: ! print >> sys.stderr, "anydbm module unavailable." return 1 elif opt in ("-d", "--dbm"): --- 82,86 ---- dbopen = anydbm.open except AttributeError: ! sys.stderr.write("anydbm module unavailable.\n") return 1 elif opt in ("-d", "--dbm"): *************** *** 88,97 **** dbopen = dbm.open except AttributeError: ! print >> sys.stderr, "dbm module unavailable." return 1 if dbopen is None: if bsddb is None: ! print >> sys.stderr, "bsddb module unavailable -" ! print >> sys.stderr, "must specify dbtype." return 1 else: --- 88,97 ---- dbopen = dbm.open except AttributeError: ! sys.stderr.write("dbm module unavailable.\n") return 1 if dbopen is None: if bsddb is None: ! sys.stderr.write("bsddb module unavailable - ") ! sys.stderr.write("must specify dbtype.\n") return 1 else: *************** *** 101,106 **** db = dbopen(dbfile, 'r') except bsddb.error: ! print >> sys.stderr, "Unable to open", dbfile, ! print >> sys.stderr, "Check for format or version mismatch." return 1 --- 101,106 ---- db = dbopen(dbfile, 'r') except bsddb.error: ! sys.stderr.write("Unable to open %s. " % dbfile) ! sys.stderr.write("Check for format or version mismatch.\n") return 1 From gvanrossum@users.sourceforge.net Mon Feb 3 15:28:24 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 03 Feb 2003 07:28:24 -0800 Subject: [Python-checkins] python/dist/src/Objects longobject.c,1.154,1.155 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv21734 Modified Files: longobject.c Log Message: _PyLong_Sign(): remove an assert that needed a variable ndigits that wasn't used outside the assert (and hence caused a compiler warning about an unused variable in NDEBUG mode). The assert wasn't very useful any more. _PyLong_NumBits(): moved the calculation of ndigits after asserting that v != NULL. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.154 retrieving revision 1.155 diff -C2 -d -r1.154 -r1.155 *** longobject.c 2 Feb 2003 17:33:53 -0000 1.154 --- longobject.c 3 Feb 2003 15:28:19 -0000 1.155 *************** *** 265,273 **** { PyLongObject *v = (PyLongObject *)vv; - const int ndigits = ABS(v->ob_size); assert(v != NULL); assert(PyLong_Check(v)); - assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); return v->ob_size == 0 ? 0 : (v->ob_size < 0 ? -1 : 1); --- 265,271 ---- *************** *** 279,286 **** PyLongObject *v = (PyLongObject *)vv; size_t result = 0; ! int ndigits = ABS(v->ob_size); assert(v != NULL); assert(PyLong_Check(v)); assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); if (ndigits > 0) { --- 277,285 ---- PyLongObject *v = (PyLongObject *)vv; size_t result = 0; ! int ndigits; assert(v != NULL); assert(PyLong_Check(v)); + ndigits = ABS(v->ob_size); assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); if (ndigits > 0) { From akuchling@users.sourceforge.net Mon Feb 3 15:36:30 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Mon, 03 Feb 2003 07:36:30 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libos.tex,1.109,1.110 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv25340 Modified Files: libos.tex Log Message: Bug #678077: Suggest alternative to os.getlogin() Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.109 retrieving revision 1.110 diff -C2 -d -r1.109 -r1.110 *** libos.tex 7 Jan 2003 22:43:25 -0000 1.109 --- libos.tex 3 Feb 2003 15:36:26 -0000 1.110 *************** *** 142,146 **** Return the name of the user logged in on the controlling terminal of the process. For most purposes, it is more useful to use the ! environment variable \envvar{LOGNAME} to find out who the user is. Availability: \UNIX. \end{funcdesc} --- 142,148 ---- Return the name of the user logged in on the controlling terminal of the process. For most purposes, it is more useful to use the ! environment variable \envvar{LOGNAME} to find out who the user is, ! or \code{pwd.getpwuid(os.getuid())[0]} to get the login name ! of the currently effective user ID. Availability: \UNIX. \end{funcdesc} From tim_one@users.sourceforge.net Mon Feb 3 15:45:59 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 03 Feb 2003 07:45:59 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.116,2.117 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv29027/Modules Modified Files: cPickle.c Log Message: PDATA_PUSH and PDATA_APPEND. documented, and reformatted for better readability. load_bool(): Now that I know the intended difference between _PUSH and _APPEND, used the right one. Pdata_grow(): Squashed out a redundant overflow test. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.116 retrieving revision 2.117 diff -C2 -d -r2.116 -r2.117 *** cPickle.c 2 Feb 2003 20:29:39 -0000 2.116 --- cPickle.c 3 Feb 2003 15:45:56 -0000 2.117 *************** *** 189,196 **** size_t nbytes; - if (! self->size) - goto nomemory; bigger = self->size << 1; ! if (bigger <= 0) goto nomemory; if ((int)(size_t)bigger != bigger) --- 189,194 ---- size_t nbytes; bigger = self->size << 1; ! if (bigger <= 0) /* was 0, or new value overflows */ goto nomemory; if ((int)(size_t)bigger != bigger) *************** *** 211,227 **** } ! /* D is a Pdata *. Pop the topmost element and store it into V, which ! * must be an lvalue holding PyObject *. On stack underflow, UnpicklingError * is raised and V is set to NULL. D and V may be evaluated several times. */ #define PDATA_POP(D, V) { \ ! if ((D)->length) \ ! (V) = (D)->data[--((D)->length)]; \ ! else { \ ! PyErr_SetString(UnpicklingError, "bad pickle data"); \ ! (V) = NULL; \ ! } \ } static PyObject * Pdata_popTuple(Pdata *self, int start) --- 209,253 ---- } ! /* D is a Pdata*. Pop the topmost element and store it into V, which ! * must be an lvalue holding PyObject*. On stack underflow, UnpicklingError * is raised and V is set to NULL. D and V may be evaluated several times. */ #define PDATA_POP(D, V) { \ ! if ((D)->length) \ ! (V) = (D)->data[--((D)->length)]; \ ! else { \ ! PyErr_SetString(UnpicklingError, "bad pickle data"); \ ! (V) = NULL; \ ! } \ ! } ! ! /* PDATA_PUSH and PDATA_APPEND both push rvalue PyObject* O on to Pdata* ! * D. If the Pdata stack can't be grown to hold the new value, both ! * raise MemoryError and execute "return ER". The difference is in ownership ! * of O after: _PUSH transfers ownership of O from the caller to the stack ! * (no incref of O is done, and in case of error O is decrefed), while ! * _APPEND pushes a new reference. ! */ ! ! /* Push O on stack D, giving ownership of O to the stack. */ ! #define PDATA_PUSH(D, O, ER) { \ ! if (((Pdata*)(D))->length == ((Pdata*)(D))->size && \ ! Pdata_grow((Pdata*)(D)) < 0) { \ ! Py_DECREF(O); \ ! return ER; \ ! } \ ! ((Pdata*)(D))->data[((Pdata*)(D))->length++] = (O); \ } + /* Push O on stack D, pushing a new reference. */ + #define PDATA_APPEND(D, O, ER) { \ + if (((Pdata*)(D))->length == ((Pdata*)(D))->size && \ + Pdata_grow((Pdata*)(D)) < 0) \ + return ER; \ + Py_INCREF(O); \ + ((Pdata*)(D))->data[((Pdata*)(D))->length++] = (O); \ + } + + static PyObject * Pdata_popTuple(Pdata *self, int start) *************** *** 256,276 **** } - #define PDATA_APPEND(D,O,ER) { \ - if (((Pdata*)(D))->length == ((Pdata*)(D))->size && \ - Pdata_grow((Pdata*)(D)) < 0) \ - return ER; \ - Py_INCREF(O); \ - ((Pdata*)(D))->data[((Pdata*)(D))->length++]=O; \ - } - - #define PDATA_PUSH(D,O,ER) { \ - if (((Pdata*)(D))->length == ((Pdata*)(D))->size && \ - Pdata_grow((Pdata*)(D)) < 0) { \ - Py_DECREF(O); \ - return ER; \ - } \ - ((Pdata*)(D))->data[((Pdata*)(D))->length++]=O; \ - } - /*************************************************************************/ --- 282,285 ---- *************** *** 2887,2892 **** { assert(boolean == Py_True || boolean == Py_False); ! Py_INCREF(boolean); ! PDATA_PUSH(self->stack, boolean, -1); return 0; } --- 2896,2900 ---- { assert(boolean == Py_True || boolean == Py_False); ! PDATA_APPEND(self->stack, boolean, -1); return 0; } From montanaro@users.sourceforge.net Mon Feb 3 15:48:17 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 03 Feb 2003 07:48:17 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.637,1.638 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv31587 Modified Files: NEWS Log Message: braino Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.637 retrieving revision 1.638 diff -C2 -d -r1.637 -r1.638 *** NEWS 3 Feb 2003 15:17:25 -0000 1.637 --- NEWS 3 Feb 2003 15:48:10 -0000 1.638 *************** *** 189,194 **** example: ! % python2.2 -h some.db > some.pickle ! % python2.3 -h some.db.new < some.pickle Run the scripts without any args to get a usage message. --- 189,194 ---- example: ! % python2.2 db2pickle.py -h some.db > some.pickle ! % python2.3 pickle2db.py -h some.db.new < some.pickle Run the scripts without any args to get a usage message. From tim_one@users.sourceforge.net Mon Feb 3 16:20:21 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 03 Feb 2003 08:20:21 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv14251/python/Lib/test Modified Files: pickletester.py Log Message: Proper testing of proto 2 in part requires checking that the new opcodes are actually getting generated. Add helpered method ensure_opcode_in_pickle to do a correct job checking for that. Changed test_long1(), test_long4(), and test_short_tuples() to use it. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** pickletester.py 2 Feb 2003 20:29:38 -0000 1.37 --- pickletester.py 3 Feb 2003 16:20:13 -0000 1.38 *************** *** 1,4 **** --- 1,5 ---- import unittest import pickle + import pickletools from test.test_support import TestFailed, have_unicode, TESTFN *************** *** 254,257 **** --- 255,264 ---- pass + def ensure_opcode_in_pickle(self, code, pickle): + for op, dummy, dummy in pickletools.genops(pickle): + if op.code == code: + return + self.fail("didn't find opcode %r in pickle %r" % (code, pickle)) + def test_misc(self): # test various datatypes not tested by testdata *************** *** 477,480 **** --- 484,488 ---- y = self.loads(s) self.assertEqual(x, y) + self.ensure_opcode_in_pickle(pickle.LONG1, s) def test_long4(self): *************** *** 483,486 **** --- 491,495 ---- y = self.loads(s) self.assertEqual(x, y) + self.ensure_opcode_in_pickle(pickle.LONG4, s) def test_short_tuples(self): *************** *** 504,509 **** (2, 4): pickle.TUPLE, } - all_tuple_opcodes = (pickle.TUPLE, pickle.EMPTY_TUPLE, - pickle.TUPLE1, pickle.TUPLE2, pickle.TUPLE3) a = () b = (1,) --- 513,516 ---- *************** *** 516,529 **** y = self.loads(s) self.assertEqual(x, y, (proto, x, s, y)) - - # Verify that the protocol-correct tuple-building opcode - # was generated. expected = expected_opcode[proto, len(x)] ! for opcode in s: ! if opcode in all_tuple_opcodes: ! self.assertEqual(expected, opcode) ! break ! else: ! self.fail("didn't find a tuple-building opcode in pickle") def test_singletons(self): --- 523,528 ---- y = self.loads(s) self.assertEqual(x, y, (proto, x, s, y)) expected = expected_opcode[proto, len(x)] ! self.ensure_opcode_in_pickle(expected, s) def test_singletons(self): From montanaro@users.sourceforge.net Mon Feb 3 15:17:31 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 03 Feb 2003 07:17:31 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.636,1.637 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv16232 Modified Files: NEWS Log Message: add note about new db2pickle.py and pickle2db.py scripts Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.636 retrieving revision 1.637 diff -C2 -d -r1.636 -r1.637 *** NEWS 2 Feb 2003 07:51:32 -0000 1.636 --- NEWS 3 Feb 2003 15:17:25 -0000 1.637 *************** *** 179,183 **** ----------- ! TBD Build --- 179,197 ---- ----------- ! - Two new scripts (db2pickle.py and pickle2db.py) were added to the ! Tools/scripts directory to facilitate conversion from the old bsddb module ! to the new one. While the user-visible API of the new module is ! compatible with the old one, it's likely that the version of the ! underlying database library has changed. To convert from the old library, ! run the db2pickle.py script using the old version of Python to convert it ! to a pickle file. After upgrading Python, run the pickle2db.py script ! using the new version of Python to reconstitute your database. For ! example: ! ! % python2.2 -h some.db > some.pickle ! % python2.3 -h some.db.new < some.pickle ! ! Run the scripts without any args to get a usage message. ! Build *************** *** 627,631 **** still available in source code, but not built automatically anymore, and is now named bsddb185. This supports Berkeley DB versions from ! 3.0 to 4.1. - unicodedata was updated to Unicode 3.2. It supports normalization --- 641,648 ---- still available in source code, but not built automatically anymore, and is now named bsddb185. This supports Berkeley DB versions from ! 3.0 to 4.1. For help converting your databases from the old module (which ! probably used an obsolete version of Berkeley DB) to the new module, see ! the db2pickle.py and pickle2db.py scripts described in the Tools/Demos ! section above. - unicodedata was updated to Unicode 3.2. It supports normalization From gvanrossum@users.sourceforge.net Mon Feb 3 16:59:54 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 03 Feb 2003 08:59:54 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.140,1.141 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv19418 Modified Files: pickle.py Log Message: Support keyword argument 'bin', with a pending deprecation warning. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.140 retrieving revision 1.141 diff -C2 -d -r1.140 -r1.141 *** pickle.py 2 Feb 2003 20:29:38 -0000 1.140 --- pickle.py 3 Feb 2003 16:59:48 -0000 1.141 *************** *** 168,172 **** class Pickler: ! def __init__(self, file, proto=0): """This takes a file-like object for writing a pickle data stream. --- 168,172 ---- class Pickler: ! def __init__(self, file, proto=None, bin=None): """This takes a file-like object for writing a pickle data stream. *************** *** 192,195 **** --- 192,203 ---- """ + if proto is not None and bin is not None: + raise ValueError, "can't specify both 'proto' and 'bin' arguments" + if bin is not None: + warnings.warn("The 'bin' argument to Pickler() is deprecated", + PendingDeprecationWarning) + proto = bin + if proto is None: + proto = 0 if proto < 0: proto = 2 *************** *** 1465,1474 **** from StringIO import StringIO ! def dump(obj, file, proto=0): ! Pickler(file, proto).dump(obj) ! def dumps(obj, proto=0): file = StringIO() ! Pickler(file, proto).dump(obj) return file.getvalue() --- 1473,1482 ---- from StringIO import StringIO ! def dump(obj, file, proto=None, bin=None): ! Pickler(file, proto, bin).dump(obj) ! def dumps(obj, proto=None, bin=None): file = StringIO() ! Pickler(file, proto, bin).dump(obj) return file.getvalue() From montanaro@users.sourceforge.net Mon Feb 3 17:24:21 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 03 Feb 2003 09:24:21 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv31512 Modified Files: test_csv.py Log Message: replicate Excel tests with a dialect using TABs as the delimiter and colons as the quotechar. All this duplication probably isn't needed. Hopefully it helps cover a few more lines in _csv.c though. Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** test_csv.py 3 Feb 2003 06:45:59 -0000 1.10 --- test_csv.py 3 Feb 2003 17:24:18 -0000 1.11 *************** *** 112,115 **** --- 112,212 ---- self.writerAssertEqual([[1, 2, 'a\nbc', 3, 4]], '1,2,"a\nbc",3,4\r\n') + class MyWeirdDialect(csv.excel): + quotechar = ':' + delimiter = '\t' + + class TestExcelTabsColons(TestCsvBase): + dialect = MyWeirdDialect() + + def test_single(self): + self.readerAssertEqual('abc', [['abc']]) + + def test_simple(self): + self.readerAssertEqual('1\t2\t3\t4\t5', [['1','2','3','4','5']]) + + def test_blankline(self): + self.readerAssertEqual('', []) + + def test_empty_fields(self): + self.readerAssertEqual('\t', [['', '']]) + + def test_singlequoted(self): + self.readerAssertEqual('::', [['']]) + + def test_singlequoted_left_empty(self): + self.readerAssertEqual('::\t', [['','']]) + + def test_singlequoted_right_empty(self): + self.readerAssertEqual('\t::', [['','']]) + + def test_single_quoted_quote(self): + self.readerAssertEqual('::::', [[':']]) + + def test_quoted_quotes(self): + self.readerAssertEqual('::::::', [['::']]) + + def test_inline_quote(self): + self.readerAssertEqual('a::b', [['a::b']]) + + def test_inline_quotes(self): + self.readerAssertEqual('a:b:c', [['a:b:c']]) + + def test_quotes_and_more(self): + self.readerAssertEqual(':a:b', [['ab']]) + + def test_lone_quote(self): + self.readerAssertEqual('a:b', [['a:b']]) + + def test_quote_and_quote(self): + self.readerAssertEqual(':a: :b:', [['a :b:']]) + + def test_space_and_quote(self): + self.readerAssertEqual(' :a:', [[' :a:']]) + + def test_quoted(self): + self.readerAssertEqual('1\t2\t3\t:I think,\ttherefore I am:\t5\t6', + [['1', '2', '3', + 'I think,\ttherefore I am', + '5', '6']]) + + def test_quoted_quote(self): + self.readerAssertEqual('1\t2\t3\t:"I see,"\tsaid the blind man:\t:as he picked up his hammer and saw:', + [['1', '2', '3', + '"I see,"\tsaid the blind man', + 'as he picked up his hammer and saw']]) + + def test_quoted_nl(self): + input = '''\ + 1\t2\t3\t:"I see," + \tsaid the blind man:\t:as he picked up his + hammer and saw: + 9\t8\t7\t6''' + self.readerAssertEqual(input, + [['1', '2', '3', + '"I see,"\n\tsaid the blind man', + 'as he picked up his\nhammer and saw'], + ['9','8','7','6']]) + + def test_dubious_quote(self): + self.readerAssertEqual('12\t12\t1:\t', [['12', '12', '1:', '']]) + + def test_null(self): + self.writerAssertEqual([], '') + + def test_single(self): + self.writerAssertEqual([['abc']], 'abc\r\n') + + def test_simple(self): + self.writerAssertEqual([[1, 2, 'abc', 3, 4]], '1\t2\tabc\t3\t4\r\n') + + def test_quotes(self): + self.writerAssertEqual([[1, 2, 'a:bc:', 3, 4]], '1\t2\t:a::bc:::\t3\t4\r\n') + + def test_quote_fieldsep(self): + self.writerAssertEqual([['abc\tdef']], ':abc\tdef:\r\n') + + def test_newlines(self): + self.writerAssertEqual([[1, 2, 'a\nbc', 3, 4]], '1\t2\t:a\nbc:\t3\t4\r\n') + class TestDictFields(unittest.TestCase): def test_simple_dict(self): From montanaro@users.sourceforge.net Mon Feb 3 17:28:59 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 03 Feb 2003 09:28:59 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv896 Modified Files: test_csv.py Log Message: that was a dumb waste of time. I should have known there was no code in _csv.c that depended on specific delimiters and quotechars... Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** test_csv.py 3 Feb 2003 17:24:18 -0000 1.11 --- test_csv.py 3 Feb 2003 17:28:55 -0000 1.12 *************** *** 112,212 **** self.writerAssertEqual([[1, 2, 'a\nbc', 3, 4]], '1,2,"a\nbc",3,4\r\n') - class MyWeirdDialect(csv.excel): - quotechar = ':' - delimiter = '\t' - - class TestExcelTabsColons(TestCsvBase): - dialect = MyWeirdDialect() - - def test_single(self): - self.readerAssertEqual('abc', [['abc']]) - - def test_simple(self): - self.readerAssertEqual('1\t2\t3\t4\t5', [['1','2','3','4','5']]) - - def test_blankline(self): - self.readerAssertEqual('', []) - - def test_empty_fields(self): - self.readerAssertEqual('\t', [['', '']]) - - def test_singlequoted(self): - self.readerAssertEqual('::', [['']]) - - def test_singlequoted_left_empty(self): - self.readerAssertEqual('::\t', [['','']]) - - def test_singlequoted_right_empty(self): - self.readerAssertEqual('\t::', [['','']]) - - def test_single_quoted_quote(self): - self.readerAssertEqual('::::', [[':']]) - - def test_quoted_quotes(self): - self.readerAssertEqual('::::::', [['::']]) - - def test_inline_quote(self): - self.readerAssertEqual('a::b', [['a::b']]) - - def test_inline_quotes(self): - self.readerAssertEqual('a:b:c', [['a:b:c']]) - - def test_quotes_and_more(self): - self.readerAssertEqual(':a:b', [['ab']]) - - def test_lone_quote(self): - self.readerAssertEqual('a:b', [['a:b']]) - - def test_quote_and_quote(self): - self.readerAssertEqual(':a: :b:', [['a :b:']]) - - def test_space_and_quote(self): - self.readerAssertEqual(' :a:', [[' :a:']]) - - def test_quoted(self): - self.readerAssertEqual('1\t2\t3\t:I think,\ttherefore I am:\t5\t6', - [['1', '2', '3', - 'I think,\ttherefore I am', - '5', '6']]) - - def test_quoted_quote(self): - self.readerAssertEqual('1\t2\t3\t:"I see,"\tsaid the blind man:\t:as he picked up his hammer and saw:', - [['1', '2', '3', - '"I see,"\tsaid the blind man', - 'as he picked up his hammer and saw']]) - - def test_quoted_nl(self): - input = '''\ - 1\t2\t3\t:"I see," - \tsaid the blind man:\t:as he picked up his - hammer and saw: - 9\t8\t7\t6''' - self.readerAssertEqual(input, - [['1', '2', '3', - '"I see,"\n\tsaid the blind man', - 'as he picked up his\nhammer and saw'], - ['9','8','7','6']]) - - def test_dubious_quote(self): - self.readerAssertEqual('12\t12\t1:\t', [['12', '12', '1:', '']]) - - def test_null(self): - self.writerAssertEqual([], '') - - def test_single(self): - self.writerAssertEqual([['abc']], 'abc\r\n') - - def test_simple(self): - self.writerAssertEqual([[1, 2, 'abc', 3, 4]], '1\t2\tabc\t3\t4\r\n') - - def test_quotes(self): - self.writerAssertEqual([[1, 2, 'a:bc:', 3, 4]], '1\t2\t:a::bc:::\t3\t4\r\n') - - def test_quote_fieldsep(self): - self.writerAssertEqual([['abc\tdef']], ':abc\tdef:\r\n') - - def test_newlines(self): - self.writerAssertEqual([[1, 2, 'a\nbc', 3, 4]], '1\t2\t:a\nbc:\t3\t4\r\n') - class TestDictFields(unittest.TestCase): def test_simple_dict(self): --- 112,115 ---- From montanaro@users.sourceforge.net Mon Feb 3 17:37:34 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 03 Feb 2003 09:37:34 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv5816 Modified Files: test_csv.py Log Message: a few more productive tests dealing with quoting and escaping. Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_csv.py 3 Feb 2003 17:28:55 -0000 1.12 --- test_csv.py 3 Feb 2003 17:37:29 -0000 1.13 *************** *** 112,115 **** --- 112,141 ---- self.writerAssertEqual([[1, 2, 'a\nbc', 3, 4]], '1,2,"a\nbc",3,4\r\n') + class EscapedExcel(csv.excel): + quoting = csv.QUOTE_NONE + escapechar = '\\' + + class TestEscapedExcel(TestCsvBase): + dialect = EscapedExcel() + + def test_escape_fieldsep(self): + self.writerAssertEqual([['abc,def']], 'abc\\,def\r\n') + + def test_read_escape_fieldsep(self): + self.readerAssertEqual('abc\\,def\r\n', [['abc,def']]) + + class QuotedEscapedExcel(csv.excel): + quoting = csv.QUOTE_NONNUMERIC + escapechar = '\\' + + class TestQuotedEscapedExcel(TestCsvBase): + dialect = QuotedEscapedExcel() + + def test_write_escape_fieldsep(self): + self.writerAssertEqual([['abc,def']], '"abc,def"\r\n') + + def test_read_escape_fieldsep(self): + self.readerAssertEqual('"abc\\,def"\r\n', [['abc,def']]) + class TestDictFields(unittest.TestCase): def test_simple_dict(self): From gvanrossum@users.sourceforge.net Mon Feb 3 17:50:21 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 03 Feb 2003 09:50:21 -0800 Subject: [Python-checkins] python/nondist/peps pep-0307.txt,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv12555 Modified Files: pep-0307.txt Log Message: Misc tweaks and updates. Index: pep-0307.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0307.txt,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pep-0307.txt 1 Feb 2003 20:10:35 -0000 1.5 --- pep-0307.txt 3 Feb 2003 17:50:16 -0000 1.6 *************** *** 27,30 **** --- 27,36 ---- CVS for Python 2.3). + This PEP attempts to fully document the interface between pickled + objects and the pickling process, highlighting additions by + specifying "new in this PEP". (The interface to invoke pickling + or unpickling is not covered fully, except for the changes to the + API for specifying the pickling protocol to picklers.) + Motivation *************** *** 79,82 **** --- 85,97 ---- This works in previous Python versions, too. + The pickle.py module has supported passing the 'bin' value as a + keyword argument rather than a positional argument. (This is not + recommended, since cPickle only accepts positional arguments, but + it works...) Passing 'bin' as a keyword argument is deprecated, + and a PendingDeprecationWarning is issued in this case. You have + to invoke the Python interpreter with -Wa or a variation on that + to see PendingDeprecationWarning messages. In Python 2.4, the + warning class may be upgraded to DeprecationWarning. + Security issues *************** *** 106,109 **** --- 121,127 ---- unauthenticated source *** + The same warning applies to previous Python versions, despite the + presence of safety checks there. + Extended __reduce__ API *************** *** 185,188 **** --- 203,215 ---- state with value None. + A __reduce__ implementation that needs to work both under Python + 2.2 and under Python 2.3 could check the variable + pickle.format_version to determine whether to use the listitems + and dictitems features. If this value is >= "2.0" then they are + supported. If not, any list or dict items should be incorporated + somehow in the 'state' return value; the __setstate__ method + should be prepared to accept list or dict items as part of the + state (how this is done is up to the application). + The __newobj__ unpickling function *************** *** 205,208 **** --- 232,239 ---- function named __newobj__ that returns something different, you deserve what you get. + + It is safe to use this feature under Python 2.2; there's nothing + in the recommended implementation of __newobj__ that depends on + Python 2.3. From gvanrossum@users.sourceforge.net Mon Feb 3 18:10:15 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 03 Feb 2003 10:10:15 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.141,1.142 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv23466 Modified Files: pickle.py Log Message: _slotnames(): exclude __dict__ and __weakref__; these aren't real slots even though they can be listed in __slots__. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.141 retrieving revision 1.142 diff -C2 -d -r1.141 -r1.142 *** pickle.py 3 Feb 2003 16:59:48 -0000 1.141 --- pickle.py 3 Feb 2003 18:10:09 -0000 1.142 *************** *** 882,886 **** for c in cls.__mro__: if "__slots__" in c.__dict__: ! names += list(c.__dict__["__slots__"]) return names --- 882,887 ---- for c in cls.__mro__: if "__slots__" in c.__dict__: ! names += [name for name in c.__dict__["__slots__"] ! if name not in ("__dict__", "__weakref__")] return names From akuchling@users.sourceforge.net Mon Feb 3 19:11:22 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Mon, 03 Feb 2003 11:11:22 -0800 Subject: [Python-checkins] python/dist/src/Lib BaseHTTPServer.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv17964 Modified Files: BaseHTTPServer.py Log Message: [Bug #676292] BaseHTTPServer incorrectly parses protocol; fix by Andrew Dalke * Treat major, minor numbers of HTTP version as separate integers * Fix errors if version string is "HTTP/1.2.3" or even simply "BLAH". * send_error() checks if 'self.command' is a HEAD. However, if there's an error parsing the first line of the HTTP request the self.command wasn't set yet; force self.command to be initialized to None. Index: BaseHTTPServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/BaseHTTPServer.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** BaseHTTPServer.py 3 Feb 2003 15:21:15 -0000 1.23 --- BaseHTTPServer.py 3 Feb 2003 19:11:18 -0000 1.24 *************** *** 227,230 **** --- 227,231 ---- """ + self.command = None # set in case of error on the first line self.request_version = version = "HTTP/0.9" # Default self.close_connection = 1 *************** *** 242,254 **** return False try: ! version_number = float(version.split('/', 1)[1]) ! except ValueError: self.send_error(400, "Bad request version (%s)" % `version`) return False ! if version_number >= 1.1 and self.protocol_version >= "HTTP/1.1": self.close_connection = 0 ! if version_number >= 2.0: self.send_error(505, ! "Invalid HTTP Version (%f)" % version_number) return False elif len(words) == 2: --- 243,265 ---- return False try: ! base_version_number = version.split('/', 1)[1] ! version_number = base_version_number.split(".") ! # RFC 2145 section 3.1 says there can be only one "." and ! # - major and minor numbers MUST be treated as ! # separate integers; ! # - HTTP/2.4 is a lower version than HTTP/2.13, which in ! # turn is lower than HTTP/12.3; ! # - Leading zeros MUST be ignored by recipients. ! if len(version_number) != 2: ! raise ValueError ! version_number = int(version_number[0]), int(version_number[1]) ! except (ValueError, IndexError): self.send_error(400, "Bad request version (%s)" % `version`) return False ! if version_number >= (1, 1) and self.protocol_version >= "HTTP/1.1": self.close_connection = 0 ! if version_number >= (2, 0): self.send_error(505, ! "Invalid HTTP Version (%s)" % base_version_number) return False elif len(words) == 2: From gvanrossum@users.sourceforge.net Mon Feb 3 19:46:58 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 03 Feb 2003 11:46:58 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.142,1.143 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv2565 Modified Files: pickle.py Log Message: _slotnames(): this is a fairly expensive calculation. Cache the outcome as __slotnames__ on the class. (Like __slots__, it's not safe to ask for this as an attribute -- you must look for it in the specific class's __dict__. But it must be set using attribute notation, because __dict__ is a read-only proxy.) Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.142 retrieving revision 1.143 diff -C2 -d -r1.142 -r1.143 *** pickle.py 3 Feb 2003 18:10:09 -0000 1.142 --- pickle.py 3 Feb 2003 19:46:54 -0000 1.143 *************** *** 877,887 **** defined.) """ ! if not hasattr(cls, "__slots__"): ! return [] names = [] ! for c in cls.__mro__: ! if "__slots__" in c.__dict__: ! names += [name for name in c.__dict__["__slots__"] ! if name not in ("__dict__", "__weakref__")] return names --- 877,904 ---- defined.) """ ! ! # Get the value from a cache in the class if possible ! names = cls.__dict__.get("__slotnames__") ! if names is not None: ! return names ! ! # Not cached -- calculate the value names = [] ! if not hasattr(cls, "__slots__"): ! # This class has no slots ! pass ! else: ! # Slots found -- gather slot names from all base classes ! for c in cls.__mro__: ! if "__slots__" in c.__dict__: ! names += [name for name in c.__dict__["__slots__"] ! if name not in ("__dict__", "__weakref__")] ! ! # Cache the outcome in the class if at all possible ! try: ! cls.__slotnames__ = names ! except: ! pass # But don't die if we can't ! return names From doerwalter@users.sourceforge.net Mon Feb 3 20:17:21 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Mon, 03 Feb 2003 12:17:21 -0800 Subject: [Python-checkins] python/dist/src/Lib/test/output test_pow,1.2,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory sc8-pr-cvs1:/tmp/cvs-serv15333/Lib/test/output Removed Files: test_pow Log Message: Port test_pow.py to PyUnit. From SF patch #662807 --- test_pow DELETED --- From doerwalter@users.sourceforge.net Mon Feb 3 20:17:21 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Mon, 03 Feb 2003 12:17:21 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_pow.py,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv15333/Lib/test Modified Files: test_pow.py Log Message: Port test_pow.py to PyUnit. From SF patch #662807 Index: test_pow.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pow.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** test_pow.py 7 Dec 2002 10:05:27 -0000 1.16 --- test_pow.py 3 Feb 2003 20:17:19 -0000 1.17 *************** *** 1,125 **** ! import sys ! from test import test_support ! def powtest(type): ! if type != float: ! print " Testing 2-argument pow() function..." ! for i in range(-1000, 1000): ! if pow(type(i), 0) != 1: ! raise ValueError, 'pow('+str(i)+',0) != 1' ! if pow(type(i), 1) != type(i): ! raise ValueError, 'pow('+str(i)+',1) != '+str(i) ! if pow(type(0), 1) != type(0): ! raise ValueError, 'pow(0,'+str(i)+') != 0' ! if pow(type(1), 1) != type(1): ! raise ValueError, 'pow(1,'+str(i)+') != 1' ! for i in range(-100, 100): ! if pow(type(i), 3) != i*i*i: ! raise ValueError, 'pow('+str(i)+',3) != '+str(i*i*i) ! pow2 = 1 ! for i in range(0,31): ! if pow(2, i) != pow2: ! raise ValueError, 'pow(2,'+str(i)+') != '+str(pow2) ! if i != 30 : pow2 = pow2*2 ! for othertype in int, long: ! for i in range(-10, 0) + range(1, 10): ! ii = type(i) ! for j in range(1, 11): ! jj = -othertype(j) ! try: pow(ii, jj) - except ValueError: - raise ValueError, "pow(%s, %s) failed" % (ii, jj) ! for othertype in int, long, float: ! for i in range(1, 100): ! zero = type(0) ! exp = -othertype(i/10.0) ! if exp == 0: ! continue ! try: ! pow(zero, exp) ! except ZeroDivisionError: ! pass # taking zero to any negative exponent should fail ! else: ! raise ValueError, "pow(%s, %s) did not fail" % (zero, exp) ! print " Testing 3-argument pow() function..." ! il, ih = -20, 20 ! jl, jh = -5, 5 ! kl, kh = -10, 10 ! compare = cmp ! if type == float: ! il = 1 ! compare = test_support.fcmp ! elif type == int: ! jl = 0 ! elif type == long: ! jl, jh = 0, 15 ! for i in range(il, ih+1): ! for j in range(jl, jh+1): ! for k in range(kl, kh+1): ! if k != 0: ! if type == float or j < 0: ! try: ! pow(type(i),j,k) ! except TypeError: ! pass ! else: ! raise ValueError, "expected TypeError from " + \ ! "pow%r" % ((type(i), j, k),) ! continue ! if compare(pow(type(i),j,k), pow(type(i),j)% type(k)): ! raise ValueError, "pow(" +str(i)+ "," +str(j)+ \ ! "," +str(k)+ ") != pow(" +str(i)+ "," + \ ! str(j)+ ") % " +str(k) ! print 'Testing integer mode...' ! powtest(int) ! print 'Testing long integer mode...' ! powtest(long) ! print 'Testing floating point mode...' ! powtest(float) ! # Other tests-- not very systematic ! print 'The number in both columns should match.' ! print `pow(3,3) % 8`, `pow(3,3,8)` ! print `pow(3,3) % -8`, `pow(3,3,-8)` ! print `pow(3,2) % -2`, `pow(3,2,-2)` ! print `pow(-3,3) % 8`, `pow(-3,3,8)` ! print `pow(-3,3) % -8`, `pow(-3,3,-8)` ! print `pow(5,2) % -8`, `pow(5,2,-8)` ! print ! print `pow(3L,3L) % 8`, `pow(3L,3L,8)` ! print `pow(3L,3L) % -8`, `pow(3L,3L,-8)` ! print `pow(3L,2) % -2`, `pow(3L,2,-2)` ! print `pow(-3L,3L) % 8`, `pow(-3L,3L,8)` ! print `pow(-3L,3L) % -8`, `pow(-3L,3L,-8)` ! print `pow(5L,2) % -8`, `pow(5L,2,-8)` ! print ! print ! for i in range(-10, 11): ! for j in range(0, 6): ! for k in range(-7, 11): ! if j >= 0 and k != 0: ! o = pow(i,j) % k ! n = pow(i,j,k) ! if o != n: print 'Integer mismatch:', i,j,k ! if j >= 0 and k != 0: ! o = pow(long(i),j) % k ! n = pow(long(i),j,k) ! if o != n: print 'Integer mismatch:', i,j,k ! class TestRpow: ! def __rpow__(self, other): ! return None ! None ** TestRpow() # Won't fail when __rpow__ invoked. SF bug #643260. --- 1,111 ---- ! import test.test_support, unittest + class PowTest(unittest.TestCase): ! def powtest(self, type): ! if type != float: ! for i in range(-1000, 1000): ! self.assertEquals(pow(type(i), 0), 1) ! self.assertEquals(pow(type(i), 1), type(i)) ! self.assertEquals(pow(type(0), 1), type(0)) ! self.assertEquals(pow(type(1), 1), type(1)) ! for i in range(-100, 100): ! self.assertEquals(pow(type(i), 3), i*i*i) ! pow2 = 1 ! for i in range(0,31): ! self.assertEquals(pow(2, i), pow2) ! if i != 30 : pow2 = pow2*2 ! for othertype in int, long: ! for i in range(-10, 0) + range(1, 10): ! ii = type(i) ! for j in range(1, 11): ! jj = -othertype(j) pow(ii, jj) ! for othertype in int, long, float: ! for i in range(1, 100): ! zero = type(0) ! exp = -othertype(i/10.0) ! if exp == 0: ! continue ! self.assertRaises(ZeroDivisionError, pow, zero, exp) ! il, ih = -20, 20 ! jl, jh = -5, 5 ! kl, kh = -10, 10 ! asseq = self.assertEqual ! if type == float: ! il = 1 ! asseq = self.assertAlmostEqual ! elif type == int: ! jl = 0 ! elif type == long: ! jl, jh = 0, 15 ! for i in range(il, ih+1): ! for j in range(jl, jh+1): ! for k in range(kl, kh+1): ! if k != 0: ! if type == float or j < 0: ! self.assertRaises(TypeError, pow, type(i), j, k) ! continue ! asseq( ! pow(type(i),j,k), ! pow(type(i),j)% type(k) ! ) + def test_powint(self): + self.powtest(int) ! def test_powlong(self): ! self.powtest(long) ! def test_powfloat(self): ! self.powtest(float) ! def test_other(self): ! # Other tests-- not very systematic ! self.assertEquals(pow(3,3) % 8, pow(3,3,8)) ! self.assertEquals(pow(3,3) % -8, pow(3,3,-8)) ! self.assertEquals(pow(3,2) % -2, pow(3,2,-2)) ! self.assertEquals(pow(-3,3) % 8, pow(-3,3,8)) ! self.assertEquals(pow(-3,3) % -8, pow(-3,3,-8)) ! self.assertEquals(pow(5,2) % -8, pow(5,2,-8)) ! self.assertEquals(pow(3L,3L) % 8, pow(3L,3L,8)) ! self.assertEquals(pow(3L,3L) % -8, pow(3L,3L,-8)) ! self.assertEquals(pow(3L,2) % -2, pow(3L,2,-2)) ! self.assertEquals(pow(-3L,3L) % 8, pow(-3L,3L,8)) ! self.assertEquals(pow(-3L,3L) % -8, pow(-3L,3L,-8)) ! self.assertEquals(pow(5L,2) % -8, pow(5L,2,-8)) ! for i in range(-10, 11): ! for j in range(0, 6): ! for k in range(-7, 11): ! if j >= 0 and k != 0: ! self.assertEquals( ! pow(i,j) % k, ! pow(i,j,k) ! ) ! if j >= 0 and k != 0: ! self.assertEquals( ! pow(long(i),j) % k, ! pow(long(i),j,k) ! ) ! def test_bug643260(self): ! class TestRpow: ! def __rpow__(self, other): ! return None ! None ** TestRpow() # Won't fail when __rpow__ invoked. SF bug #643260. ! ! def test_main(): ! suite = unittest.TestSuite() ! suite.addTest(unittest.makeSuite(PowTest)) ! test.test_support.run_suite(suite) ! ! if __name__ == "__main__": ! test_main() From gvanrossum@users.sourceforge.net Mon Feb 3 20:22:26 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 03 Feb 2003 12:22:26 -0800 Subject: [Python-checkins] python/nondist/peps pep-0307.txt,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv17587 Modified Files: pep-0307.txt Log Message: Added docs for __getstate__ and __setstate__, __getinitargs__ and __getnewargs__. Unfortunately these need to be refactored again according to a different organizing principle. ;-( Index: pep-0307.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0307.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pep-0307.txt 3 Feb 2003 17:50:16 -0000 1.6 --- pep-0307.txt 3 Feb 2003 20:22:23 -0000 1.7 *************** *** 138,141 **** --- 138,145 ---- though, and we'll refer to these collectively as __reduce__. + IMPORTANT: a classic class cannot provide __reduce__ + functionality. It must use __getinitargs__ and/or __gestate__ to + customize pickling. These are described below. + __reduce__ must return either a string or a tuple. If it returns a string, this is an object whose state is not to be pickled, but *************** *** 213,216 **** --- 217,232 ---- + XXX Refactoring needed + + The following sections should really be reorganized according to + the following cases: + + 1. classic classes, all protocols + + 2. new-style classes, protocols 0 and 1 + + 3. new-style classes, protocol 2 + + The __newobj__ unpickling function *************** *** 236,239 **** --- 252,395 ---- in the recommended implementation of __newobj__ that depends on Python 2.3. + + + The __getstate__ and __setstate__ methods + + When there is no __reduce__ for an object, the primary ways to + customize pickling is by specifying __getstate__ and/or + __setstate__ methods. These are supported for classic classes as + well as for new-style classes for which no __reduce__ exists. + + When __reduce__ exists, __getstate__ is not called (unless your + __reduce__ implementation calls it), but __getstate__ will be + called with the third item from the tuple returned by __reduce__, + if not None. + + There's a subtle difference between classic and new-style classes + here: if a classic class's __getstate__ returns None, + self.__setstate__(None) will be called as part of unpickling. But + if a new-style class's __getstate__ returns None, its __setstate__ + won't be called at all as part of unpickling. + + The __getstate__ method is supposed to return a picklable version + of an object's state that does not reference the object itself. + If no __getstate__ method exists, a default state is assumed. + There are several cases: + + - For a classic class, the default state is self.__dict__. + + - For a new-style class that has an instance __dict__ and no + __slots__, the default state is self.__dict__. + + - For a new-style class that has no instance __dict__ and no + __slots__, the default __state__ is None. + + - For a new-style class that has an instance __dict__ and + __slots__, the default state is a tuple consisting of two + dictionaries: the first being self.__dict__, and the second + being a dictionary mapping slot names to slot values. Only + slots that have a value are included in the latter. + + - For a new-style class that has __slots__ and no instance + __dict__, the default state is a tuple whose first item is None + and whose second item is a dictionary mapping slot names to slot + values described in the previous bullet. + + The __setstate__ should take one argument; it will be called with + the value returned by __getstate__ or with the default state + described above if no __setstate__ method is defined. + + If no __setstate__ method exists, a default implementation is + provided that can handle the state returned by the default + __getstate__. + + It is fine if a class implements one of these but not the other, + as long as it is compatible with the default version. + + New-style classes that inherit a default __reduce__ implementation + from the ultimate base class 'object'. This implementation is not + used for protocol 2, and then last four bullets above apply. For + protocols 0 and 1, the default implementation looks for a + __getstate__ method, and if none exists, it uses a simpler default + strategy: + + - If there is an instance __dict__, the state is self.__dict__. + + - Otherwise, the state is None (and __setstate__ will not be + called). + + Note that this strategy ignores slots. New-style classes that + define slots and don't define __getstate__ in the same class that + defines the slots automatically have a __getstate__ method added + that raises TypeError. Protocol 2 ignores this __getstate__ + method (recognized by the specific text of the error message). + + + The __getinitargs__ and __getnewargs__ methods + + The __setstate__ method (or its default implementation) requires + that a new object already exists so that its __setstate__ method + can be called. The point is to create a new object that isn't + fully initialized; in particular, the class's __init__ method + should not be called if possible. + + The way this is done differs between classic and new-style + classes. + + For classic classes, these are the possibilities: + + - Normally, the following trick is used: create an instance of a + trivial classic class (one without any methods or instance + variables) and then use __class__ assignment to change its class + to the desired class. This creates an instance of the desired + class with an empty __dict__ whose __init__ has not been called. + + - However, if the class has a method named __getinitargs__, the + above trick is not used, and a class instance is created by + using the tuple returned by __getinitargs__ as an argument list + to the class constructor. This is done even if __getinitargs__ + returns an empty tuple -- a __getinitargs__ method that returns + () is not equivalent to not having __getinitargs__ at all. + __getinitargs__ *must* return a tuple. + + - In restricted execution mode, the trick from the first bullet + doesn't work; in this case, the class constructor is called with + an empty argument list if no __getinitargs__ method exists. + This means that in order for a classic class to be unpicklable + in restricted mode, it must either implement __getinitargs__ or + its constructor (i.e., its __init__ method) must be callable + without arguments. + + For new-style classes, these are the possibilities: + + - When using protocol 0 or 1, a default __reduce__ implementation + is normally inherited from the ultimate base class class + 'object'. This implementation finds the nearest base class that + is implemented in C (either as a built-in type or as a type + defined by an extension class). Calling this base class B and + the class of the object to be pickled C, the new object is + created at unpickling time using the following code: + + obj = B.__new__(C, state) + B.__init__(obj, state) + + where state is a value computed at pickling time as follows: + + state = B(obj) + + This only works when B is not C, and only for certain classes + B. It does work for the following built-in classes: int, long, + float, complex, str, unicode, tuple, list, dict; and this is its + main redeeming factor. + + - When using protocol 2, the default __reduce__ implementation + inherited from 'object' is ignored. Instead, a new pickling + opcode is generated that causes a new object to be created as + follows: + + obj = C.__new__(C, *args) + + where args is either the empty tuple, or the tuple returned by + the __getnewargs__ method, if defined. From doerwalter@users.sourceforge.net Mon Feb 3 20:22:30 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Mon, 03 Feb 2003 12:22:30 -0800 Subject: [Python-checkins] python/dist/src/Lib/test README,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv17586/Lib/test Modified Files: README Log Message: Fix typos. Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/README,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** README 27 Nov 2002 15:47:10 -0000 1.17 --- README 3 Feb 2003 20:22:27 -0000 1.18 *************** *** 14,18 **** testing facility provided with Python; any particular test should use only one of these options. Each option requires writing a test module using the ! conventions of the the selected option: - PyUnit_ based tests --- 14,18 ---- testing facility provided with Python; any particular test should use only one of these options. Each option requires writing a test module using the ! conventions of the selected option: - PyUnit_ based tests *************** *** 42,46 **** the interface and general guidelines on writing PyUnit based tests. ! The test_support helper module provides a two functions for use by PyUnit based tests in the Python regression testing framework: --- 42,46 ---- the interface and general guidelines on writing PyUnit based tests. ! The test_support helper module provides two functions for use by PyUnit based tests in the Python regression testing framework: From nnorwitz@users.sourceforge.net Mon Feb 3 20:23:37 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 03 Feb 2003 12:23:37 -0800 Subject: [Python-checkins] python/dist/src/Python bltinmodule.c,2.271,2.272 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv18087a/Python Modified Files: bltinmodule.c Log Message: SF #661437, apply() should get PendingDeprecation Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.271 retrieving revision 2.272 diff -C2 -d -r2.271 -r2.272 *** bltinmodule.c 25 Jan 2003 22:46:11 -0000 2.271 --- bltinmodule.c 3 Feb 2003 20:23:33 -0000 2.272 *************** *** 74,77 **** --- 74,80 ---- PyObject *t = NULL, *retval = NULL; + PyErr_Warn(PyExc_PendingDeprecationWarning, + "use func(*args, **kwargs) instead of " + "apply(func, args, kwargs)"); if (!PyArg_UnpackTuple(args, "apply", 1, 3, &func, &alist, &kwdict)) return NULL; From montanaro@users.sourceforge.net Mon Feb 3 20:25:22 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 03 Feb 2003 12:25:22 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv18989 Modified Files: csv.py Log Message: Rearrange the dialect code a bit. Add a _name attribute to the Dialect class and set it in register_dialect. Add an unregister_dialect function. Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** csv.py 3 Feb 2003 06:44:13 -0000 1.18 --- csv.py 3 Feb 2003 20:25:19 -0000 1.19 *************** *** 4,12 **** __all__ = [ "QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", "Error", "Dialect", "excel", "excel_tab", "reader", "writer", ! "register_dialect", "get_dialect", "list_dialects"] QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE = range(4) class Dialect: delimiter = ',' quotechar = '"' --- 4,31 ---- __all__ = [ "QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", "Error", "Dialect", "excel", "excel_tab", "reader", "writer", ! "register_dialect", "get_dialect", "list_dialects", ! "unregister_dialect" ] QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE = range(4) + _dialects = {} + + def register_dialect(name, dialect): + if not issubclass(dialect, Dialect): + raise TypeError, "dialect not a subclass of Dialect" + dialect._name = name + _dialects[name] = dialect() + + def get_dialect(name): + return _dialects[name] + + def list_dialects(): + return _dialects.keys() + + def unregister_dialect(name): + del _dialects[name] + class Dialect: + _name = "" delimiter = ',' quotechar = '"' *************** *** 19,30 **** class excel(Dialect): pass class excel_tab(excel): delimiter = '\t' ! ! _dialects = { ! 'excel': excel(), ! 'excel-tab': excel_tab(), ! } class _OCcsv: --- 38,46 ---- class excel(Dialect): pass + register_dialect("excel", excel) class excel_tab(excel): delimiter = '\t' ! register_dialect("excel-tab", excel_tab) class _OCcsv: *************** *** 81,95 **** for fields in lines: self.writerow(fields) - - def register_dialect(name, dialect): - if not issubclass(dialect, Dialect): - raise TypeError, "dialect not a subclass of Dialect" - _dialects[name] = dialect() - - def get_dialect(name): - return _dialects[name] - - def list_dialects(): - return _dialects.keys() # An alternate way of populating the dialects dictionary... --- 97,100 ---- From montanaro@users.sourceforge.net Mon Feb 3 20:26:28 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 03 Feb 2003 12:26:28 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv19587 Modified Files: test_csv.py Log Message: Add test for list_dialects. Call unregister_dialect where appropriate instead of fiddling _dialects directly. Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** test_csv.py 3 Feb 2003 17:37:29 -0000 1.13 --- test_csv.py 3 Feb 2003 20:26:26 -0000 1.14 *************** *** 198,206 **** self.assertEqual(isinstance(csv.get_dialect("myexceltsv"), myexceltsv), 1==1) ! del csv._dialects["myexceltsv"] def test_get(self): self.assertEqual(isinstance(csv.get_dialect("excel"), csv.excel), 1==1) def test_bad_register(self): --- 198,211 ---- self.assertEqual(isinstance(csv.get_dialect("myexceltsv"), myexceltsv), 1==1) ! csv.unregister_dialect("myexceltsv") def test_get(self): self.assertEqual(isinstance(csv.get_dialect("excel"), csv.excel), 1==1) + + def test_list(self): + for dname in csv.list_dialects(): + d = csv.get_dialect(dname) + self.assertEqual(d._name, dname) def test_bad_register(self): From gvanrossum@users.sourceforge.net Mon Feb 3 20:45:52 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 03 Feb 2003 12:45:52 -0800 Subject: [Python-checkins] python/dist/src/Lib/test/output test_zlib,1.5,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory sc8-pr-cvs1:/tmp/cvs-serv30447/Lib/test/output Removed Files: test_zlib Log Message: - Thanks to Scott David Daniels, a subtle bug in how the zlib extension implemented flush() was fixed. Scott also rewrite the zlib test suite using the unittest module. (SF bug #640230 and patch #678531.) Backport candidate I think. --- test_zlib DELETED --- From gvanrossum@users.sourceforge.net Mon Feb 3 20:45:56 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 03 Feb 2003 12:45:56 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.638,1.639 ACKS,1.225,1.226 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv30447/Misc Modified Files: NEWS ACKS Log Message: - Thanks to Scott David Daniels, a subtle bug in how the zlib extension implemented flush() was fixed. Scott also rewrite the zlib test suite using the unittest module. (SF bug #640230 and patch #678531.) Backport candidate I think. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.638 retrieving revision 1.639 diff -C2 -d -r1.638 -r1.639 *** NEWS 3 Feb 2003 15:48:10 -0000 1.638 --- NEWS 3 Feb 2003 20:45:50 -0000 1.639 *************** *** 34,37 **** --- 34,42 ---- ----------------- + - Thanks to Scott David Daniels, a subtle bug in how the zlib + extension implemented flush() was fixed. Scott also rewrite the + zlib test suite using the unittest module. (SF bug #640230 and + patch #678531.) + - Added an itertools module containing high speed, memory efficient looping constructs inspired by tools from Haskell and SML. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.225 retrieving revision 1.226 diff -C2 -d -r1.225 -r1.226 *** ACKS 27 Jan 2003 22:19:55 -0000 1.225 --- ACKS 3 Feb 2003 20:45:52 -0000 1.226 *************** *** 124,127 **** --- 124,128 ---- Lars Damerow Eric Daniel + Scott David Daniels Ben Darnell Jonathan Dasteel From gvanrossum@users.sourceforge.net Mon Feb 3 20:46:21 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 03 Feb 2003 12:46:21 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_zlib.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv30447/Lib/test Modified Files: test_zlib.py Log Message: - Thanks to Scott David Daniels, a subtle bug in how the zlib extension implemented flush() was fixed. Scott also rewrite the zlib test suite using the unittest module. (SF bug #640230 and patch #678531.) Backport candidate I think. Index: test_zlib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_zlib.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** test_zlib.py 12 Aug 2002 15:26:05 -0000 1.19 --- test_zlib.py 3 Feb 2003 20:45:48 -0000 1.20 *************** *** 1,168 **** import zlib ! import sys ! import imp ! from test.test_support import TestFailed ! try: ! t = imp.find_module('test_zlib') ! file = t[0] ! except ImportError: ! file = open(__file__) ! buf = file.read() * 8 ! file.close() ! # test the checksums (hex so the test doesn't break on 64-bit machines) ! def fix(x): ! return "0x%x" % (x & 0xffffffffL) ! print fix(zlib.crc32('penguin')), fix(zlib.crc32('penguin', 1)) ! print fix(zlib.adler32('penguin')), fix(zlib.adler32('penguin', 1)) - # make sure we generate some expected errors - try: - zlib.compress('ERROR', zlib.MAX_WBITS + 1) - except zlib.error, msg: - print "expecting", msg - try: - zlib.compressobj(1, 8, 0) - except ValueError, msg: - print "expecting", msg - try: - zlib.decompressobj(0) - except ValueError, msg: - print "expecting", msg - x = zlib.compress(buf) - y = zlib.decompress(x) - if buf != y: - print "normal compression/decompression failed" - else: - print "normal compression/decompression succeeded" ! buf = buf * 16 ! co = zlib.compressobj(8, 8, -15) ! x1 = co.compress(buf) ! x2 = co.flush() ! try: ! co.flush() ! print "Oops - second flush worked when it should not have!" ! except zlib.error: ! pass ! x = x1 + x2 ! dc = zlib.decompressobj(-15) ! y1 = dc.decompress(x) ! y2 = dc.flush() ! y = y1 + y2 ! if buf != y: ! print "compress/decompression obj failed" ! else: ! print "compress/decompression obj succeeded" ! co = zlib.compressobj(2, 8, -12, 9, 1) ! bufs = [] ! for i in range(0, len(buf), 256): ! bufs.append(co.compress(buf[i:i+256])) ! bufs.append(co.flush()) ! combuf = ''.join(bufs) ! decomp1 = zlib.decompress(combuf, -12, -5) ! if decomp1 != buf: ! print "decompress with init options failed" ! else: ! print "decompress with init options succeeded" ! deco = zlib.decompressobj(-12) ! bufs = [] ! for i in range(0, len(combuf), 128): ! bufs.append(deco.decompress(combuf[i:i+128])) ! bufs.append(deco.flush()) ! decomp2 = ''.join(bufs) ! if decomp2 != buf: ! print "decompressobj with init options failed" ! else: ! print "decompressobj with init options succeeded" - print "should be '':", `deco.unconsumed_tail` - # Check a decompression object with max_length specified - deco = zlib.decompressobj(-12) - cb = combuf - bufs = [] - while cb: - max_length = 1 + len(cb)/10 - chunk = deco.decompress(cb, max_length) - if len(chunk) > max_length: - print 'chunk too big (%d>%d)' % (len(chunk),max_length) - bufs.append(chunk) - cb = deco.unconsumed_tail - bufs.append(deco.flush()) - decomp2 = ''.join(buf) - if decomp2 != buf: - print "max_length decompressobj failed" - else: - print "max_length decompressobj succeeded" ! # Misc tests of max_length ! deco = zlib.decompressobj(-12) ! try: ! deco.decompress("", -1) ! except ValueError: ! pass ! else: ! print "failed to raise value error on bad max_length" ! print "unconsumed_tail should be '':", `deco.unconsumed_tail` ! # Test flush() with the various options, using all the different levels ! # in order to provide more variations. ! sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH'] ! sync_opt = [getattr(zlib, opt) for opt in sync_opt if hasattr(zlib, opt)] ! for sync in sync_opt: ! for level in range(10): ! obj = zlib.compressobj( level ) ! d = obj.compress( buf[:3000] ) ! d = d + obj.flush( sync ) ! d = d + obj.compress( buf[3000:] ) ! d = d + obj.flush() ! if zlib.decompress(d) != buf: ! print "Decompress failed: flush mode=%i, level=%i" % (sync,level) ! del obj - # Test for the odd flushing bugs noted in 2.0, and hopefully fixed in 2.1 - import random - random.seed(1) ! print 'Testing on 17K of random data' ! if hasattr(zlib, 'Z_SYNC_FLUSH'): ! # Create compressor and decompressor objects ! c=zlib.compressobj(9) ! d=zlib.decompressobj() ! # Try 17K of data ! # generate random data stream ! a="" ! for i in range(17*1024): ! a=a+chr(random.randint(0,255)) ! # compress, sync-flush, and decompress ! t = d.decompress( c.compress(a)+c.flush(zlib.Z_SYNC_FLUSH) ) - # if decompressed data is different from the input data, choke. - if len(t) != len(a): - print len(a),len(t),len(d.unused_data) - raise TestFailed, "output of 17K doesn't match" - def ignore(): - """An empty function with a big string. ! Make the compression algorithm work a little harder. ! """ ! """ LAERTES --- 1,418 ---- + import unittest + from test import test_support import zlib ! import random ! # print test_support.TESTFN ! def getbuf(): ! # This was in the original. Avoid non-repeatable sources. ! # Left here (unused) in case something wants to be done with it. ! import imp ! try: ! t = imp.find_module('test_zlib') ! file = t[0] ! except ImportError: ! file = open(__file__) ! buf = file.read() * 8 ! file.close() ! return buf ! class ChecksumTestCase(unittest.TestCase): ! # checksum test cases ! def test_crc32start(self): ! self.assertEqual(zlib.crc32(""), zlib.crc32("", 0)) ! def test_crc32empty(self): ! self.assertEqual(zlib.crc32("", 0), 0) ! self.assertEqual(zlib.crc32("", 1), 1) ! self.assertEqual(zlib.crc32("", 432), 432) ! def test_adler32start(self): ! self.assertEqual(zlib.adler32(""), zlib.adler32("", 1)) ! def test_adler32empty(self): ! self.assertEqual(zlib.adler32("", 0), 0) ! self.assertEqual(zlib.adler32("", 1), 1) ! self.assertEqual(zlib.adler32("", 432), 432) ! def assertEqual32(self, seen, expected): ! # 32-bit values masked -- checksums on 32- vs 64- bit machines ! # This is important if bit 31 (0x08000000L) is set. ! self.assertEqual(seen & 0x0FFFFFFFFL, expected & 0x0FFFFFFFFL) ! def test_penguins(self): ! self.assertEqual32(zlib.crc32("penguin", 0), 0x0e5c1a120L) ! self.assertEqual32(zlib.crc32("penguin", 1), 0x43b6aa94) ! self.assertEqual32(zlib.adler32("penguin", 0), 0x0bcf02f6) ! self.assertEqual32(zlib.adler32("penguin", 1), 0x0bd602f7) ! self.assertEqual(zlib.crc32("penguin"), zlib.crc32("penguin", 0)) ! self.assertEqual(zlib.adler32("penguin"),zlib.adler32("penguin",1)) ! class ExceptionTestCase(unittest.TestCase): ! # make sure we generate some expected errors ! def test_bigbits(self): ! # specifying total bits too large causes an error ! self.assertRaises(zlib.error, ! zlib.compress, 'ERROR', zlib.MAX_WBITS + 1) ! def test_badcompressobj(self): ! # verify failure on building compress object with bad params ! self.assertRaises(ValueError, zlib.compressobj, 1, 8, 0) ! def test_baddecompressobj(self): ! # verify failure on building decompress object with bad params ! self.assertRaises(ValueError, zlib.decompressobj, 0) ! class CompressTestCase(unittest.TestCase): ! # Test compression in one go (whole message compression) ! def test_speech(self): ! # decompress(compress(data)) better be data ! x = zlib.compress(hamlet_scene) ! self.assertEqual(zlib.decompress(x), hamlet_scene) ! def test_speech8(self): ! # decompress(compress(data)) better be data -- more compression chances ! data = hamlet_scene * 8 ! x = zlib.compress(data) ! self.assertEqual(zlib.decompress(x), data) ! def test_speech16(self): ! # decompress(compress(data)) better be data -- more compression chances ! data = hamlet_scene * 16 ! x = zlib.compress(data) ! self.assertEqual(zlib.decompress(x), data) ! def test_speech128(self): ! # decompress(compress(data)) better be data -- more compression chances ! data = hamlet_scene * 8 * 16 ! x = zlib.compress(data) ! self.assertEqual(zlib.decompress(x), data) ! def test_monotonic(self): ! # higher compression levels should not expand compressed size ! data = hamlet_scene * 8 * 16 ! last = length = len(zlib.compress(data, 0)) ! self.failUnless(last > len(data), "compress level 0 always expands") ! for level in range(10): ! length = len(zlib.compress(data, level)) ! self.failUnless(length <= last, ! 'compress level %d more effective than %d!' % ( ! level-1, level)) ! last = length ! class CompressObjectTestCase(unittest.TestCase): ! # Test compression object ! def test_pairsmall(self): ! # use compress object in straightforward manner, decompress w/ object ! data = hamlet_scene ! co = zlib.compressobj(8, 8, -15) ! x1 = co.compress(data) ! x2 = co.flush() ! self.assertRaises(zlib.error, co.flush) # second flush should not work ! dco = zlib.decompressobj(-15) ! y1 = dco.decompress(x1 + x2) ! y2 = dco.flush() ! self.assertEqual(data, y1 + y2) ! def test_pair(self): ! # straightforward compress/decompress objects, more compression ! data = hamlet_scene * 8 * 16 ! co = zlib.compressobj(8, 8, -15) ! x1 = co.compress(data) ! x2 = co.flush() ! self.assertRaises(zlib.error, co.flush) # second flush should not work ! dco = zlib.decompressobj(-15) ! y1 = dco.decompress(x1 + x2) ! y2 = dco.flush() ! self.assertEqual(data, y1 + y2) ! ! def test_compressincremental(self): ! # compress object in steps, decompress object as one-shot ! data = hamlet_scene * 8 * 16 ! co = zlib.compressobj(2, 8, -12, 9, 1) ! bufs = [] ! for i in range(0, len(data), 256): ! bufs.append(co.compress(data[i:i+256])) ! bufs.append(co.flush()) ! combuf = ''.join(bufs) ! ! dco = zlib.decompressobj(-15) ! y1 = dco.decompress(''.join(bufs)) ! y2 = dco.flush() ! self.assertEqual(data, y1 + y2) ! ! def test_decompressincremental(self): ! # compress object in steps, decompress object in steps ! data = hamlet_scene * 8 * 16 ! co = zlib.compressobj(2, 8, -12, 9, 1) ! bufs = [] ! for i in range(0, len(data), 256): ! bufs.append(co.compress(data[i:i+256])) ! bufs.append(co.flush()) ! combuf = ''.join(bufs) ! ! self.assertEqual(data, zlib.decompress(combuf, -12, -5)) ! ! dco = zlib.decompressobj(-12) ! bufs = [] ! for i in range(0, len(combuf), 128): ! bufs.append(dco.decompress(combuf[i:i+128])) ! self.assertEqual('', dco.unconsumed_tail, ######## ! "(A) uct should be '': not %d long" % ! len(dco.unconsumed_tail)) ! bufs.append(dco.flush()) ! self.assertEqual('', dco.unconsumed_tail, ######## ! "(B) uct should be '': not %d long" % ! len(dco.unconsumed_tail)) ! self.assertEqual(data, ''.join(bufs)) ! # Failure means: "decompressobj with init options failed" ! ! def test_decompinc(self,sizes=[128],flush=True,source=None,cx=256,dcx=64): ! # compress object in steps, decompress object in steps, loop sizes ! source = source or hamlet_scene ! for reps in sizes: ! data = source * reps ! co = zlib.compressobj(2, 8, -12, 9, 1) ! bufs = [] ! for i in range(0, len(data), cx): ! bufs.append(co.compress(data[i:i+cx])) ! bufs.append(co.flush()) ! combuf = ''.join(bufs) ! ! self.assertEqual(data, zlib.decompress(combuf, -12, -5)) ! ! dco = zlib.decompressobj(-12) ! bufs = [] ! for i in range(0, len(combuf), dcx): ! bufs.append(dco.decompress(combuf[i:i+dcx])) ! self.assertEqual('', dco.unconsumed_tail, ######## ! "(A) uct should be '': not %d long" % ! len(dco.unconsumed_tail)) ! if flush: ! bufs.append(dco.flush()) ! else: ! while True: ! chunk = dco.decompress('') ! if chunk: ! bufs.append(chunk) ! else: ! break ! self.assertEqual('', dco.unconsumed_tail, ######## ! "(B) uct should be '': not %d long" % ! len(dco.unconsumed_tail)) ! self.assertEqual(data, ''.join(bufs)) ! # Failure means: "decompressobj with init options failed" ! ! def test_decompimax(self,sizes=[128],flush=True,source=None,cx=256,dcx=64): ! # compress in steps, decompress in length-restricted steps, loop sizes ! source = source or hamlet_scene ! for reps in sizes: ! # Check a decompression object with max_length specified ! data = source * reps ! co = zlib.compressobj(2, 8, -12, 9, 1) ! bufs = [] ! for i in range(0, len(data), cx): ! bufs.append(co.compress(data[i:i+cx])) ! bufs.append(co.flush()) ! combuf = ''.join(bufs) ! self.assertEqual(data, zlib.decompress(combuf, -12, -5), ! 'compressed data failure') ! ! dco = zlib.decompressobj(-12) ! bufs = [] ! cb = combuf ! while cb: ! #max_length = 1 + len(cb)/10 ! chunk = dco.decompress(cb, dcx) ! self.failIf(len(chunk) > dcx, ! 'chunk too big (%d>%d)' % (len(chunk), dcx)) ! bufs.append(chunk) ! cb = dco.unconsumed_tail ! if flush: ! bufs.append(dco.flush()) ! else: ! while True: ! chunk = dco.decompress('', dcx) ! self.failIf(len(chunk) > dcx, ! 'chunk too big in tail (%d>%d)' % (len(chunk), dcx)) ! if chunk: ! bufs.append(chunk) ! else: ! break ! self.assertEqual(len(data), len(''.join(bufs))) ! self.assertEqual(data, ''.join(bufs), 'Wrong data retrieved') ! ! def test_decompressmaxlen(self): ! # Check a decompression object with max_length specified ! data = hamlet_scene * 8 * 16 ! co = zlib.compressobj(2, 8, -12, 9, 1) ! bufs = [] ! for i in range(0, len(data), 256): ! bufs.append(co.compress(data[i:i+256])) ! bufs.append(co.flush()) ! combuf = ''.join(bufs) ! self.assertEqual(data, zlib.decompress(combuf, -12, -5), ! 'compressed data failure') ! ! dco = zlib.decompressobj(-12) ! bufs = [] ! cb = combuf ! while cb: ! max_length = 1 + len(cb)/10 ! chunk = dco.decompress(cb, max_length) ! self.failIf(len(chunk) > max_length, ! 'chunk too big (%d>%d)' % (len(chunk),max_length)) ! bufs.append(chunk) ! cb = dco.unconsumed_tail ! bufs.append(dco.flush()) ! self.assertEqual(len(data), len(''.join(bufs))) ! self.assertEqual(data, ''.join(bufs), 'Wrong data retrieved') ! ! def test_decompressmaxlenflushless(self): ! # identical to test_decompressmaxlen except flush is replaced ! # with an equivalent. This works and other fails on (eg) 2.2.2 ! data = hamlet_scene * 8 * 16 ! co = zlib.compressobj(2, 8, -12, 9, 1) ! bufs = [] ! for i in range(0, len(data), 256): ! bufs.append(co.compress(data[i:i+256])) ! bufs.append(co.flush()) ! combuf = ''.join(bufs) ! self.assertEqual(data, zlib.decompress(combuf, -12, -5), ! 'compressed data mismatch') ! ! dco = zlib.decompressobj(-12) ! bufs = [] ! cb = combuf ! while cb: ! max_length = 1 + len(cb)/10 ! chunk = dco.decompress(cb, max_length) ! self.failIf(len(chunk) > max_length, ! 'chunk too big (%d>%d)' % (len(chunk),max_length)) ! bufs.append(chunk) ! cb = dco.unconsumed_tail ! ! #bufs.append(dco.flush()) ! while len(chunk): ! chunk = dco.decompress('', max_length) ! self.failIf(len(chunk) > max_length, ! 'chunk too big (%d>%d)' % (len(chunk),max_length)) ! bufs.append(chunk) ! ! self.assertEqual(data, ''.join(bufs), 'Wrong data retrieved') ! ! def test_maxlenmisc(self): ! # Misc tests of max_length ! dco = zlib.decompressobj(-12) ! self.assertRaises(ValueError, dco.decompress, "", -1) ! self.assertEqual('', dco.unconsumed_tail) ! ! def test_flushes(self): ! # Test flush() with the various options, using all the ! # different levels in order to provide more variations. ! sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH'] ! sync_opt = [getattr(zlib, opt) for opt in sync_opt ! if hasattr(zlib, opt)] ! data = hamlet_scene * 8 ! ! for sync in sync_opt: ! for level in range(10): ! obj = zlib.compressobj( level ) ! a = obj.compress( data[:3000] ) ! b = obj.flush( sync ) ! c = obj.compress( data[3000:] ) ! d = obj.flush() ! self.assertEqual(zlib.decompress(''.join([a,b,c,d])), ! data, ("Decompress failed: flush " ! "mode=%i, level=%i") % (sync, level)) ! del obj ! ! def test_odd_flush(self): ! # Test for odd flushing bugs noted in 2.0, and hopefully fixed in 2.1 ! import random ! ! if hasattr(zlib, 'Z_SYNC_FLUSH'): ! # Testing on 17K of "random" data ! ! # Create compressor and decompressor objects ! co = zlib.compressobj(9) ! dco = zlib.decompressobj() ! ! # Try 17K of data ! # generate random data stream ! try: ! # In 2.3 and later, WichmannHill is the RNG of the bug report ! gen = random.WichmannHill() ! except AttributeError: ! try: ! # 2.2 called it Random ! gen = random.Random() ! except AttributeError: ! # others might simply have a single RNG ! gen = random ! gen.seed(1) ! data = genblock(1, 17 * 1024, generator=gen) ! ! # compress, sync-flush, and decompress ! first = co.compress(data) ! second = co.flush(zlib.Z_SYNC_FLUSH) ! expanded = dco.decompress(first + second) ! ! # if decompressed data is different from the input data, choke. ! self.assertEqual(expanded, data, "17K random source doesn't match") ! ! def test_manydecompinc(self): ! # Run incremental decompress test for a large range of sizes ! self.test_decompinc(sizes=[1< Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv30447/Modules Modified Files: zlibmodule.c Log Message: - Thanks to Scott David Daniels, a subtle bug in how the zlib extension implemented flush() was fixed. Scott also rewrite the zlib test suite using the unittest module. (SF bug #640230 and patch #678531.) Backport candidate I think. Index: zlibmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zlibmodule.c,v retrieving revision 2.65 retrieving revision 2.66 diff -C2 -d -r2.65 -r2.66 *** zlibmodule.c 23 Jul 2002 06:31:14 -0000 2.65 --- zlibmodule.c 3 Feb 2003 20:45:47 -0000 2.66 *************** *** 657,680 **** static PyObject * PyZlib_unflush(compobject *self, PyObject *args) - /*decompressor flush is a no-op because all pending data would have been - flushed by the decompress method. However, this routine previously called - inflateEnd, causing any further decompress or flush calls to raise - exceptions. This behaviour has been preserved.*/ { ! int err; PyObject * retval = NULL; ! if (!PyArg_ParseTuple(args, "")) return NULL; ENTER_ZLIB ! err = inflateEnd(&(self->zst)); ! if (err != Z_OK) ! zlib_error(self->zst, err, "from inflateEnd()"); ! else { ! self->is_initialised = 0; ! retval = PyString_FromStringAndSize(NULL, 0); } LEAVE_ZLIB --- 657,711 ---- static PyObject * PyZlib_unflush(compobject *self, PyObject *args) { ! int err, length = DEFAULTALLOC; PyObject * retval = NULL; + unsigned long start_total_out; ! if (!PyArg_ParseTuple(args, "|i:flush", &length)) ! return NULL; ! if (!(retval = PyString_FromStringAndSize(NULL, length))) return NULL; + ENTER_ZLIB ! start_total_out = self->zst.total_out; ! self->zst.avail_out = length; ! self->zst.next_out = (Byte *)PyString_AS_STRING(retval); ! ! Py_BEGIN_ALLOW_THREADS ! err = inflate(&(self->zst), Z_FINISH); ! Py_END_ALLOW_THREADS ! ! /* while Z_OK and the output buffer is full, there might be more output, ! so extend the output buffer and try again */ ! while ((err == Z_OK || err == Z_BUF_ERROR) && self->zst.avail_out == 0) { ! if (_PyString_Resize(&retval, length << 1) < 0) ! goto error; ! self->zst.next_out = (Byte *)PyString_AS_STRING(retval) + length; ! self->zst.avail_out = length; ! length = length << 1; ! ! Py_BEGIN_ALLOW_THREADS ! err = inflate(&(self->zst), Z_FINISH); ! Py_END_ALLOW_THREADS ! } ! ! /* If flushmode is Z_FINISH, we also have to call deflateEnd() to free ! various data structures. Note we should only get Z_STREAM_END when ! flushmode is Z_FINISH */ ! if (err == Z_STREAM_END) { ! err = inflateEnd(&(self->zst)); ! self->is_initialised = 0; ! if (err != Z_OK) { ! zlib_error(self->zst, err, "from inflateEnd()"); ! Py_DECREF(retval); ! retval = NULL; ! goto error; ! } } + _PyString_Resize(&retval, self->zst.total_out - start_total_out); + + error: LEAVE_ZLIB *************** *** 868,871 **** --- 899,904 ---- if (ver != NULL) PyModule_AddObject(m, "ZLIB_VERSION", ver); + + PyModule_AddStringConstant(m, "__version__", "1.0"); #ifdef WITH_THREAD From doerwalter@users.sourceforge.net Mon Feb 3 20:53:20 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Mon, 03 Feb 2003 12:53:20 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.639,1.640 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv2191/Misc Modified Files: NEWS Log Message: Fix typo. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.639 retrieving revision 1.640 diff -C2 -d -r1.639 -r1.640 *** NEWS 3 Feb 2003 20:45:50 -0000 1.639 --- NEWS 3 Feb 2003 20:53:14 -0000 1.640 *************** *** 35,39 **** - Thanks to Scott David Daniels, a subtle bug in how the zlib ! extension implemented flush() was fixed. Scott also rewrite the zlib test suite using the unittest module. (SF bug #640230 and patch #678531.) --- 35,39 ---- - Thanks to Scott David Daniels, a subtle bug in how the zlib ! extension implemented flush() was fixed. Scott also rewrote the zlib test suite using the unittest module. (SF bug #640230 and patch #678531.) From montanaro@users.sourceforge.net Mon Feb 3 21:22:40 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 03 Feb 2003 13:22:40 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv README,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv18228 Modified Files: README Log Message: updated Index: README =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/README,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** README 29 Jan 2003 14:18:20 -0000 1.2 --- README 3 Feb 2003 21:22:37 -0000 1.3 *************** *** 1,6 **** ! This little corner of the sandbox aims to create a module to read and write ! CSV files. Involved parties are currently Kevin Altis, Dave Cole, Skip ! Montanaro, Cliff Wells and Andrew McNamara. ! Stay tuned... --- 1,25 ---- ! This little corner of the sandbox contains a fairly complete csv module ! based on PEP 305 and drawing heavily on the code in Object Craft's original ! csv module. If you'd like to try it out simply execute ! python setup.py install + There is a moderately accurate library reference manual section in + libcsv.tex, though you will have to read the raw source for the time being. + You may also find PEP 305 helpful. + + Please send feedback, including bug reports, to csv@mail.mojam.com. You can + browse the list archives at + + http://manatee.mojam.com/pipermail/csv/ + + and subscribe to the list at + + http://manatee.mojam.com/mailman/listinfo/csv + + + Kevin Altis + Dave Cole + Andrew McNamara + Skip Montanaro + Cliff Wells From tim_one@users.sourceforge.net Mon Feb 3 21:31:26 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 03 Feb 2003 13:31:26 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.38,1.39 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv22080/Lib/test Modified Files: pickletester.py Log Message: Do a better job of testing that opcodes aren't generated under protocols earlier than the ones in which they were introduced. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** pickletester.py 3 Feb 2003 16:20:13 -0000 1.38 --- pickletester.py 3 Feb 2003 21:31:22 -0000 1.39 *************** *** 255,263 **** pass ! def ensure_opcode_in_pickle(self, code, pickle): for op, dummy, dummy in pickletools.genops(pickle): if op.code == code: ! return ! self.fail("didn't find opcode %r in pickle %r" % (code, pickle)) def test_misc(self): --- 255,264 ---- pass ! # Return True if opcode code appears in the pickle, else False. ! def opcode_in_pickle(self, code, pickle): for op, dummy, dummy in pickletools.genops(pickle): if op.code == code: ! return True ! return False def test_misc(self): *************** *** 481,495 **** def test_long1(self): x = 12345678910111213141516178920L ! s = self.dumps(x, 2) ! y = self.loads(s) ! self.assertEqual(x, y) ! self.ensure_opcode_in_pickle(pickle.LONG1, s) def test_long4(self): x = 12345678910111213141516178920L << (256*8) ! s = self.dumps(x, 2) ! y = self.loads(s) ! self.assertEqual(x, y) ! self.ensure_opcode_in_pickle(pickle.LONG4, s) def test_short_tuples(self): --- 482,500 ---- def test_long1(self): x = 12345678910111213141516178920L ! for proto in protocols: ! s = self.dumps(x, proto) ! y = self.loads(s) ! self.assertEqual(x, y) ! self.assertEqual(self.opcode_in_pickle(pickle.LONG1, s), ! proto >= 2) def test_long4(self): x = 12345678910111213141516178920L << (256*8) ! for proto in protocols: ! s = self.dumps(x, proto) ! y = self.loads(s) ! self.assertEqual(x, y) ! self.assertEqual(self.opcode_in_pickle(pickle.LONG4, s), ! proto >= 2) def test_short_tuples(self): *************** *** 524,530 **** self.assertEqual(x, y, (proto, x, s, y)) expected = expected_opcode[proto, len(x)] ! self.ensure_opcode_in_pickle(expected, s) def test_singletons(self): for proto in protocols: for x in None, False, True: --- 529,548 ---- self.assertEqual(x, y, (proto, x, s, y)) expected = expected_opcode[proto, len(x)] ! self.assertEqual(self.opcode_in_pickle(expected, s), True) def test_singletons(self): + # Map (proto, singleton) to expected opcode. + expected_opcode = {(0, None): pickle.NONE, + (1, None): pickle.NONE, + (2, None): pickle.NONE, + + (0, True): pickle.INT, + (1, True): pickle.INT, + (2, True): pickle.NEWTRUE, + + (0, False): pickle.INT, + (1, False): pickle.INT, + (2, False): pickle.NEWFALSE, + } for proto in protocols: for x in None, False, True: *************** *** 532,541 **** y = self.loads(s) self.assert_(x is y, (proto, x, s, y)) ! ! # Test that proto >= 2 really uses the bool opcodes. ! if proto >= 2 and x in (False, True): ! expected = x and pickle.NEWTRUE or pickle.NEWFALSE ! # Skip the PROTO opcode at the start. ! self.assertEqual(s[2], expected) def test_newobj_tuple(self): --- 550,555 ---- y = self.loads(s) self.assert_(x is y, (proto, x, s, y)) ! expected = expected_opcode[proto, x] ! self.assertEqual(self.opcode_in_pickle(expected, s), True) def test_newobj_tuple(self): From tim_one@users.sourceforge.net Mon Feb 3 22:07:30 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 03 Feb 2003 14:07:30 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.117,2.118 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv8214/Modules Modified Files: cPickle.c Log Message: load_counted_long(): Changed a ValueError to an UnpicklingError, just because it seems more consistent with the rest of the code. cPickle_PyMapping_HasKey(): This extern function isn't used anywhere in Python or Zope, so got rid of it. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.117 retrieving revision 2.118 diff -C2 -d -r2.117 -r2.118 *** cPickle.c 3 Feb 2003 15:45:56 -0000 2.117 --- cPickle.c 3 Feb 2003 22:07:24 -0000 2.118 *************** *** 361,378 **** static int put2(Picklerobject *, PyObject *); - int - cPickle_PyMapping_HasKey(PyObject *o, PyObject *key) - { - PyObject *v; - - if ((v = PyObject_GetItem(o,key))) { - Py_DECREF(v); - return 1; - } - - PyErr_Clear(); - return 0; - } - static PyObject * --- 361,364 ---- *************** *** 3023,3027 **** * this. */ ! PyErr_SetString(PyExc_ValueError, "LONG pickle has negative " "byte count"); return -1; --- 3009,3013 ---- * this. */ ! PyErr_SetString(UnpicklingError, "LONG pickle has negative " "byte count"); return -1; From tim_one@users.sourceforge.net Mon Feb 3 22:27:40 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 03 Feb 2003 14:27:40 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.39,1.40 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv18134/Lib/test Modified Files: pickletester.py Log Message: Added a bit to the EXT[124] tests, and refactored them to squash code duplication. Note that these still don't get run under cPickle. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** pickletester.py 3 Feb 2003 21:31:22 -0000 1.39 --- pickletester.py 3 Feb 2003 22:27:38 -0000 1.40 *************** *** 10,13 **** --- 10,21 ---- protocols = range(3) + + # Return True if opcode code appears in the pickle, else False. + def opcode_in_pickle(code, pickle): + for op, dummy, dummy in pickletools.genops(pickle): + if op.code == code: + return True + return False + class C: def __cmp__(self, other): *************** *** 255,265 **** pass - # Return True if opcode code appears in the pickle, else False. - def opcode_in_pickle(self, code, pickle): - for op, dummy, dummy in pickletools.genops(pickle): - if op.code == code: - return True - return False - def test_misc(self): # test various datatypes not tested by testdata --- 263,266 ---- *************** *** 486,491 **** y = self.loads(s) self.assertEqual(x, y) ! self.assertEqual(self.opcode_in_pickle(pickle.LONG1, s), ! proto >= 2) def test_long4(self): --- 487,491 ---- y = self.loads(s) self.assertEqual(x, y) ! self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2) def test_long4(self): *************** *** 495,500 **** y = self.loads(s) self.assertEqual(x, y) ! self.assertEqual(self.opcode_in_pickle(pickle.LONG4, s), ! proto >= 2) def test_short_tuples(self): --- 495,499 ---- y = self.loads(s) self.assertEqual(x, y) ! self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2) def test_short_tuples(self): *************** *** 529,533 **** self.assertEqual(x, y, (proto, x, s, y)) expected = expected_opcode[proto, len(x)] ! self.assertEqual(self.opcode_in_pickle(expected, s), True) def test_singletons(self): --- 528,532 ---- self.assertEqual(x, y, (proto, x, s, y)) expected = expected_opcode[proto, len(x)] ! self.assertEqual(opcode_in_pickle(expected, s), True) def test_singletons(self): *************** *** 551,555 **** self.assert_(x is y, (proto, x, s, y)) expected = expected_opcode[proto, x] ! self.assertEqual(self.opcode_in_pickle(expected, s), True) def test_newobj_tuple(self): --- 550,554 ---- self.assert_(x is y, (proto, x, s, y)) expected = expected_opcode[proto, x] ! self.assertEqual(opcode_in_pickle(expected, s), True) def test_newobj_tuple(self): *************** *** 599,609 **** self.assertEqual(x.foo, y.foo) self.assertEqual(x.bar, y.bar) - ## import pickletools - ## print - ## pickletools.dis(s) ! def test_global_ext1(self): import copy_reg ! copy_reg.add_extension(__name__, "MyList", 0xf0) try: x = MyList([1, 2, 3]) --- 598,608 ---- self.assertEqual(x.foo, y.foo) self.assertEqual(x.bar, y.bar) ! # Register a type with copy_reg, with extension code extcode. Pickle ! # an object of that type. Check that the resulting pickle uses opcode ! # (EXT[124]) under proto 2, and not in proto 1. ! def produce_global_ext(self, extcode, opcode): import copy_reg ! copy_reg.add_extension(__name__, "MyList", extcode) try: x = MyList([1, 2, 3]) *************** *** 611,615 **** x.bar = "hello" ! # Dump using protocol 1 for comparison s1 = self.dumps(x, 1) y = self.loads(s1) --- 610,614 ---- x.bar = "hello" ! # Dump using protocol 1 for comparison. s1 = self.dumps(x, 1) y = self.loads(s1) *************** *** 618,626 **** self.assert_(s1.find(__name__) >= 0) self.assert_(s1.find("MyList") >= 0) - ## import pickletools - ## print - ## pickletools.dis(s1) ! # Dump using protocol 2 for test s2 = self.dumps(x, 2) self.assertEqual(s2.find(__name__), -1) --- 617,622 ---- self.assert_(s1.find(__name__) >= 0) self.assert_(s1.find("MyList") >= 0) ! # Dump using protocol 2 for test. s2 = self.dumps(x, 2) self.assertEqual(s2.find(__name__), -1) *************** *** 629,666 **** self.assertEqual(list(x), list(y)) self.assertEqual(x.__dict__, y.__dict__) ! ## import pickletools ! ## print ! ## pickletools.dis(s2) finally: ! copy_reg.remove_extension(__name__, "MyList", 0xf0) def test_global_ext2(self): ! import copy_reg ! copy_reg.add_extension(__name__, "MyList", 0xfff0) ! try: ! x = MyList() ! s2 = self.dumps(x, 2) ! self.assertEqual(s2.find(__name__), -1) ! self.assertEqual(s2.find("MyList"), -1) ! y = self.loads(s2) ! self.assertEqual(list(x), list(y)) ! self.assertEqual(x.__dict__, y.__dict__) ! finally: ! copy_reg.remove_extension(__name__, "MyList", 0xfff0) def test_global_ext4(self): ! import copy_reg ! copy_reg.add_extension(__name__, "MyList", 0xfffff0) ! try: ! x = MyList() ! s2 = self.dumps(x, 2) ! self.assertEqual(s2.find(__name__), -1) ! self.assertEqual(s2.find("MyList"), -1) ! y = self.loads(s2) ! self.assertEqual(list(x), list(y)) ! self.assertEqual(x.__dict__, y.__dict__) ! finally: ! copy_reg.remove_extension(__name__, "MyList", 0xfffff0) class MyInt(int): --- 625,642 ---- self.assertEqual(list(x), list(y)) self.assertEqual(x.__dict__, y.__dict__) ! self.assertEqual(opcode_in_pickle(opcode, s2), True) finally: ! copy_reg.remove_extension(__name__, "MyList", extcode) ! ! def test_global_ext1(self): ! self.produce_global_ext(0xf0, pickle.EXT1) def test_global_ext2(self): ! self.produce_global_ext(0xfff0, pickle.EXT2) def test_global_ext4(self): ! self.produce_global_ext(0xffffff0, pickle.EXT4) ! class MyInt(int): From tim_one@users.sourceforge.net Mon Feb 3 22:28:43 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 03 Feb 2003 14:28:43 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.40,1.41 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv18846/Lib/test Modified Files: pickletester.py Log Message: test_newobj_generic(): Use the global protocols vector instead of a hardcoded list. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** pickletester.py 3 Feb 2003 22:27:38 -0000 1.40 --- pickletester.py 3 Feb 2003 22:28:41 -0000 1.41 *************** *** 571,575 **** def test_newobj_generic(self): ! for proto in [0, 1, 2]: for C in myclasses: B = C.__base__ --- 571,575 ---- def test_newobj_generic(self): ! for proto in protocols: for C in myclasses: B = C.__base__ From tim_one@users.sourceforge.net Mon Feb 3 22:32:20 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 03 Feb 2003 14:32:20 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv20221/Lib/test Modified Files: pickletester.py Log Message: test_newobj_tuple(), test_newobj_list(): These tests should work under all protocols, so tried them under all. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** pickletester.py 3 Feb 2003 22:28:41 -0000 1.41 --- pickletester.py 3 Feb 2003 22:32:18 -0000 1.42 *************** *** 556,563 **** x.foo = 42 x.bar = "hello" ! s = self.dumps(x, 2) ! y = self.loads(s) ! self.assertEqual(tuple(x), tuple(y)) ! self.assertEqual(x.__dict__, y.__dict__) def test_newobj_list(self): --- 556,564 ---- x.foo = 42 x.bar = "hello" ! for proto in protocols: ! s = self.dumps(x, proto) ! y = self.loads(s) ! self.assertEqual(tuple(x), tuple(y)) ! self.assertEqual(x.__dict__, y.__dict__) def test_newobj_list(self): *************** *** 565,572 **** x.foo = 42 x.bar = "hello" ! s = self.dumps(x, 2) ! y = self.loads(s) ! self.assertEqual(list(x), list(y)) ! self.assertEqual(x.__dict__, y.__dict__) def test_newobj_generic(self): --- 566,574 ---- x.foo = 42 x.bar = "hello" ! for proto in protocols: ! s = self.dumps(x, proto) ! y = self.loads(s) ! self.assertEqual(list(x), list(y)) ! self.assertEqual(x.__dict__, y.__dict__) def test_newobj_generic(self): From doerwalter@users.sourceforge.net Mon Feb 3 23:03:52 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Mon, 03 Feb 2003 15:03:52 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_sys.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv3087/Lib/test Added Files: test_sys.py Log Message: Add a new test script that tests various features of the sys module. This increases code coverage of Python/sysmodule.c from 68% to 77% (on Linux). The script doesn't exercise the error branch that handles an evil or lost sys.excepthook in Python/pythonrun.c::PyErr_PrintEx(). Also this script might not work on Jython in its current form. >From SF patch #662807. --- NEW FILE: test_sys.py --- # -*- coding: iso-8859-1 -*- import unittest, test.test_support import sys, cStringIO class SysModuleTest(unittest.TestCase): def test_original_displayhook(self): import __builtin__ savestdout = sys.stdout out = cStringIO.StringIO() sys.stdout = out dh = sys.__displayhook__ self.assertRaises(TypeError, dh) if hasattr(__builtin__, "_"): del __builtin__._ dh(None) self.assertEqual(out.getvalue(), "") self.assert_(not hasattr(__builtin__, "_")) dh(42) self.assertEqual(out.getvalue(), "42\n") self.assertEqual(__builtin__._, 42) del sys.stdout self.assertRaises(RuntimeError, dh, 42) sys.stdout = savestdout def test_lost_displayhook(self): olddisplayhook = sys.displayhook del sys.displayhook code = compile("42", "", "single") self.assertRaises(RuntimeError, eval, code) sys.displayhook = olddisplayhook def test_custom_displayhook(self): olddisplayhook = sys.displayhook def baddisplayhook(obj): raise ValueError sys.displayhook = baddisplayhook code = compile("42", "", "single") self.assertRaises(ValueError, eval, code) sys.displayhook = olddisplayhook def test_original_excepthook(self): savestderr = sys.stderr err = cStringIO.StringIO() sys.stderr = err eh = sys.__excepthook__ self.assertRaises(TypeError, eh) try: raise ValueError(42) except ValueError, exc: eh(*sys.exc_info()) sys.stderr = savestderr self.assert_(err.getvalue().endswith("ValueError: 42\n")) # FIXME: testing the code for a lost or replace excepthook in # Python/pythonrun.c::PyErr_PrintEx() is tricky. def test_exit(self): self.assertRaises(TypeError, sys.exit, 42, 42) # call without argument try: sys.exit(0) except SystemExit, exc: self.assertEquals(exc.code, 0) except: self.fail("wrong exception") else: self.fail("no exception") # call with tuple argument with one entry # entry will be unpacked try: sys.exit(42) except SystemExit, exc: self.assertEquals(exc.code, 42) except: self.fail("wrong exception") else: self.fail("no exception") # call with integer argument try: sys.exit((42,)) except SystemExit, exc: self.assertEquals(exc.code, 42) except: self.fail("wrong exception") else: self.fail("no exception") # call with string argument try: sys.exit("exit") except SystemExit, exc: self.assertEquals(exc.code, "exit") except: self.fail("wrong exception") else: self.fail("no exception") # call with tuple argument with two entries try: sys.exit((17, 23)) except SystemExit, exc: self.assertEquals(exc.code, (17, 23)) except: self.fail("wrong exception") else: self.fail("no exception") def test_getdefaultencoding(self): if test.test_support.have_unicode: self.assertRaises(TypeError, sys.getdefaultencoding, 42) # can't check more than the type, as the user might have changed it self.assert_(isinstance(sys.getdefaultencoding(), str)) # testing sys.settrace() is done in test_trace.py # testing sys.setprofile() is done in test_profile.py def test_setcheckinterval(self): self.assertRaises(TypeError, sys.setcheckinterval) sys.setcheckinterval(120) sys.setcheckinterval(100) def test_recursionlimit(self): self.assertRaises(TypeError, sys.getrecursionlimit, 42) oldlimit = sys.getrecursionlimit() self.assertRaises(TypeError, sys.setrecursionlimit) self.assertRaises(ValueError, sys.setrecursionlimit, -42) sys.setrecursionlimit(10000) self.assertEqual(sys.getrecursionlimit(), 10000) sys.setrecursionlimit(oldlimit) def test_getwindowsversion(self): if hasattr(sys, "getwindowsversion"): v = sys.getwindowsversion() self.assert_(isinstance(v, tuple)) self.assertEqual(len(v), 5) self.assert_(isinstance(v[0], int)) self.assert_(isinstance(v[1], int)) self.assert_(isinstance(v[2], int)) self.assert_(isinstance(v[3], int)) self.assert_(isinstance(v[4], str)) def test_dlopenflags(self): if hasattr(sys, "setdlopenflags"): self.assert_(hasattr(sys, "getdlopenflags")) self.assertRaises(TypeError, sys.getdlopenflags, 42) oldflags = sys.getdlopenflags() self.assertRaises(TypeError, sys.setdlopenflags) sys.setdlopenflags(oldflags+1) self.assertEqual(sys.getdlopenflags(), oldflags+1) sys.setdlopenflags(oldflags) def test_refcount(self): self.assertRaises(TypeError, sys.getrefcount) c = sys.getrefcount(None) n = None self.assertEqual(sys.getrefcount(None), c+1) del n self.assertEqual(sys.getrefcount(None), c) if hasattr(sys, "gettotalrefcount"): self.assert_(isinstance(sys.gettotalrefcount(), int)) def test_getframe(self): self.assertRaises(TypeError, sys._getframe, 42, 42) self.assertRaises(ValueError, sys._getframe, sys.maxint) self.assert_( SysModuleTest.test_getframe.im_func.func_code \ is sys._getframe().f_code ) def test_attributes(self): self.assert_(isinstance(sys.api_version, int)) self.assert_(isinstance(sys.argv, list)) self.assert_(sys.byteorder in ("little", "big")) self.assert_(isinstance(sys.builtin_module_names, tuple)) self.assert_(isinstance(sys.copyright, basestring)) self.assert_(isinstance(sys.exec_prefix, basestring)) self.assert_(isinstance(sys.executable, basestring)) self.assert_(isinstance(sys.hexversion, int)) self.assert_(isinstance(sys.maxint, int)) self.assert_(isinstance(sys.maxunicode, int)) self.assert_(isinstance(sys.platform, basestring)) self.assert_(isinstance(sys.prefix, basestring)) self.assert_(isinstance(sys.version, basestring)) vi = sys.version_info self.assert_(isinstance(vi, tuple)) self.assertEqual(len(vi), 5) self.assert_(isinstance(vi[0], int)) self.assert_(isinstance(vi[1], int)) self.assert_(isinstance(vi[2], int)) self.assert_(vi[3] in ("alpha", "beta", "candidate", "final")) self.assert_(isinstance(vi[4], int)) def test_main(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(SysModuleTest)) test.test_support.run_suite(suite) if __name__ == "__main__": test_main() From doerwalter@users.sourceforge.net Mon Feb 3 23:05:30 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Mon, 03 Feb 2003 15:05:30 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_sys.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv4103/Lib/test Modified Files: test_sys.py Log Message: Fix typo. Index: test_sys.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sys.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_sys.py 3 Feb 2003 23:03:49 -0000 1.1 --- test_sys.py 3 Feb 2003 23:05:27 -0000 1.2 *************** *** 61,65 **** self.assert_(err.getvalue().endswith("ValueError: 42\n")) ! # FIXME: testing the code for a lost or replace excepthook in # Python/pythonrun.c::PyErr_PrintEx() is tricky. --- 61,65 ---- self.assert_(err.getvalue().endswith("ValueError: 42\n")) ! # FIXME: testing the code for a lost or replaced excepthook in # Python/pythonrun.c::PyErr_PrintEx() is tricky. From tim_one@users.sourceforge.net Tue Feb 4 00:21:10 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 03 Feb 2003 16:21:10 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.118,2.119 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv2555/Modules Modified Files: cPickle.c Log Message: Brought some module variables into synch with pickle.py's current values. Imported the extension-registry dicts from copy_reg.py, in preparation for tackling EXT[124]. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.118 retrieving revision 2.119 diff -C2 -d -r2.118 -r2.119 *** cPickle.c 3 Feb 2003 22:07:24 -0000 2.118 --- cPickle.c 4 Feb 2003 00:21:07 -0000 2.119 *************** *** 96,102 **** static PyObject *BadPickleGet; static PyObject *dispatch_table; ! static PyObject *empty_tuple; static PyObject *__class___str, *__getinitargs___str, *__dict___str, --- 96,112 ---- static PyObject *BadPickleGet; + /* As the name says, an empty tuple. */ + static PyObject *empty_tuple; + /* copy_reg.dispatch_table, {type_object: pickling_function} */ static PyObject *dispatch_table; ! ! /* For EXT[124] opcodes. */ ! /* copy_reg.extension_registry, {(module_name, function_name): code} */ ! static PyObject *extension_registry; ! /* copy_reg.inverted_registry, {code: (module_name, function_name)} */ ! static PyObject *inverted_registry; ! /* copy_reg.extension_cache, {code: object} */ ! static PyObject *extension_cache; static PyObject *__class___str, *__getinitargs___str, *__dict___str, *************** *** 2593,2605 **** if (PyEval_GetRestricted()) { /* Restricted execution, get private tables */ ! PyObject *m; ! if (!( m=PyImport_Import(copy_reg_str))) goto err; ! self->dispatch_table=PyObject_GetAttr(m, dispatch_table_str); Py_DECREF(m); ! if (!( self->dispatch_table )) goto err; } else { ! self->dispatch_table=dispatch_table; Py_INCREF(dispatch_table); } --- 2603,2617 ---- if (PyEval_GetRestricted()) { /* Restricted execution, get private tables */ ! PyObject *m = PyImport_Import(copy_reg_str); ! if (m == NULL) ! goto err; ! self->dispatch_table = PyObject_GetAttr(m, dispatch_table_str); Py_DECREF(m); ! if (self->dispatch_table == NULL) ! goto err; } else { ! self->dispatch_table = dispatch_table; Py_INCREF(dispatch_table); } *************** *** 5078,5083 **** one in restricted mode. */ dispatch_table = PyObject_GetAttr(copy_reg, dispatch_table_str); ! if (!dispatch_table) ! return -1; Py_DECREF(copy_reg); --- 5090,5106 ---- one in restricted mode. */ dispatch_table = PyObject_GetAttr(copy_reg, dispatch_table_str); ! if (!dispatch_table) return -1; ! ! extension_registry = PyObject_GetAttrString(copy_reg, ! "extension_registry"); ! if (!extension_registry) return -1; ! ! inverted_registry = PyObject_GetAttrString(copy_reg, ! "inverted_registry"); ! if (!inverted_registry) return -1; ! ! extension_cache = PyObject_GetAttrString(copy_reg, ! "extension_cache"); ! if (!extension_cache) return -1; Py_DECREF(copy_reg); *************** *** 5169,5173 **** PyObject *m, *d, *di, *v, *k; int i; ! char *rev="1.71"; PyObject *format_version; PyObject *compatible_formats; --- 5192,5196 ---- PyObject *m, *d, *di, *v, *k; int i; ! char *rev = "1.71"; /* XXX when does this change? */ PyObject *format_version; PyObject *compatible_formats; *************** *** 5178,5184 **** /* Initialize some pieces. We need to do this before module creation, ! so we're forced to use a temporary dictionary. :( ! */ ! di=PyDict_New(); if (!di) return; if (init_stuff(di) < 0) return; --- 5201,5207 ---- /* Initialize some pieces. We need to do this before module creation, ! * so we're forced to use a temporary dictionary. :( ! */ ! di = PyDict_New(); if (!di) return; if (init_stuff(di) < 0) return; *************** *** 5191,5195 **** /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); ! PyDict_SetItemString(d,"__version__", v = PyString_FromString(rev)); Py_XDECREF(v); --- 5214,5219 ---- /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); ! v = PyString_FromString(rev); ! PyDict_SetItemString(d, "__version__", v); Py_XDECREF(v); *************** *** 5203,5209 **** Py_DECREF(di); ! format_version = PyString_FromString("1.3"); ! compatible_formats = Py_BuildValue("[sss]", "1.0", "1.1", "1.2"); ! PyDict_SetItemString(d, "format_version", format_version); PyDict_SetItemString(d, "compatible_formats", compatible_formats); --- 5227,5240 ---- Py_DECREF(di); ! /* These are purely informational; no code uses them. */ ! /* File format version we write. */ ! format_version = PyString_FromString("2.0"); ! /* Format versions we can read. */ ! compatible_formats = Py_BuildValue("[sssss]", ! "1.0", /* Original protocol 0 */ ! "1.1", /* Protocol 0 + INST */ ! "1.2", /* Original protocol 1 */ ! "1.3", /* Protocol 1 + BINFLOAT */ ! "2.0"); /* Oritinal potocol 2 */ PyDict_SetItemString(d, "format_version", format_version); PyDict_SetItemString(d, "compatible_formats", compatible_formats); From tim_one@users.sourceforge.net Tue Feb 4 00:21:09 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 03 Feb 2003 16:21:09 -0800 Subject: [Python-checkins] python/dist/src/Lib copy_reg.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv2555/Lib Modified Files: copy_reg.py Log Message: Brought some module variables into synch with pickle.py's current values. Imported the extension-registry dicts from copy_reg.py, in preparation for tackling EXT[124]. Index: copy_reg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy_reg.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** copy_reg.py 1 Feb 2003 02:16:36 -0000 1.13 --- copy_reg.py 4 Feb 2003 00:21:06 -0000 1.14 *************** *** 82,85 **** --- 82,87 ---- inverted_registry = {} # code -> key extension_cache = {} # code -> object + # Don't ever rebind those names: cPickle grabs a reference to them when + # it's initialized, and won't see a rebinding. def add_extension(module, name, code): From tim_one@users.sourceforge.net Tue Feb 4 00:30:49 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 03 Feb 2003 16:30:49 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.119,2.120 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv6800/Modules Modified Files: cPickle.c Log Message: Typo repair. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.119 retrieving revision 2.120 diff -C2 -d -r2.119 -r2.120 *** cPickle.c 4 Feb 2003 00:21:07 -0000 2.119 --- cPickle.c 4 Feb 2003 00:30:46 -0000 2.120 *************** *** 5236,5240 **** "1.2", /* Original protocol 1 */ "1.3", /* Protocol 1 + BINFLOAT */ ! "2.0"); /* Oritinal potocol 2 */ PyDict_SetItemString(d, "format_version", format_version); PyDict_SetItemString(d, "compatible_formats", compatible_formats); --- 5236,5240 ---- "1.2", /* Original protocol 1 */ "1.3", /* Protocol 1 + BINFLOAT */ ! "2.0"); /* Original protocol 2 */ PyDict_SetItemString(d, "format_version", format_version); PyDict_SetItemString(d, "compatible_formats", compatible_formats); From tim_one@users.sourceforge.net Tue Feb 4 00:38:24 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 03 Feb 2003 16:38:24 -0800 Subject: [Python-checkins] python/dist/src/Lib sets.py,1.39,1.40 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv9494/Lib Modified Files: sets.py Log Message: Whitespace normalization. Index: sets.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sets.py,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** sets.py 2 Feb 2003 16:07:53 -0000 1.39 --- sets.py 4 Feb 2003 00:38:20 -0000 1.40 *************** *** 271,275 **** return False for elt in ifilter(self._data.has_key, other, True): ! return False return True --- 271,275 ---- return False for elt in ifilter(self._data.has_key, other, True): ! return False return True From gvanrossum@users.sourceforge.net Tue Feb 4 01:54:51 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 03 Feb 2003 17:54:51 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.143,1.144 copy_reg.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv3141/Lib Modified Files: pickle.py copy_reg.py Log Message: Rename the extension registry variables to have leading underscores -- this clarifies that they are part of an internal API (albeit shared between pickle.py, copy_reg.py and cPickle.c). I'd like to do the same for copy_reg.dispatch_table, but worry that it might be used by existing code. This risk doesn't exist for the extension registry. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.143 retrieving revision 1.144 diff -C2 -d -r1.143 -r1.144 *** pickle.py 3 Feb 2003 19:46:54 -0000 1.143 --- pickle.py 4 Feb 2003 01:54:48 -0000 1.144 *************** *** 29,33 **** from types import * from copy_reg import dispatch_table, _reconstructor ! from copy_reg import extension_registry, inverted_registry, extension_cache import marshal import sys --- 29,33 ---- from types import * from copy_reg import dispatch_table, _reconstructor ! from copy_reg import _extension_registry, _inverted_registry, _extension_cache import marshal import sys *************** *** 846,850 **** if self.proto >= 2: ! code = extension_registry.get((module, name)) if code: assert code > 0 --- 846,850 ---- if self.proto >= 2: ! code = _extension_registry.get((module, name)) if code: assert code > 0 *************** *** 1239,1251 **** def get_extension(self, code): nil = [] ! obj = extension_cache.get(code, nil) if obj is not nil: self.append(obj) return ! key = inverted_registry.get(code) if not key: raise ValueError("unregistered extension code %d" % code) obj = self.find_class(*key) ! extension_cache[code] = obj self.append(obj) --- 1239,1251 ---- def get_extension(self, code): nil = [] ! obj = _extension_cache.get(code, nil) if obj is not nil: self.append(obj) return ! key = _inverted_registry.get(code) if not key: raise ValueError("unregistered extension code %d" % code) obj = self.find_class(*key) ! _extension_cache[code] = obj self.append(obj) Index: copy_reg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy_reg.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** copy_reg.py 4 Feb 2003 00:21:06 -0000 1.14 --- copy_reg.py 4 Feb 2003 01:54:49 -0000 1.15 *************** *** 79,85 **** # reserved. ! extension_registry = {} # key -> code ! inverted_registry = {} # code -> key ! extension_cache = {} # code -> object # Don't ever rebind those names: cPickle grabs a reference to them when # it's initialized, and won't see a rebinding. --- 79,85 ---- # reserved. ! _extension_registry = {} # key -> code ! _inverted_registry = {} # code -> key ! _extension_cache = {} # code -> object # Don't ever rebind those names: cPickle grabs a reference to them when # it's initialized, and won't see a rebinding. *************** *** 91,120 **** raise ValueError, "code out of range" key = (module, name) ! if (extension_registry.get(key) == code and ! inverted_registry.get(code) == key): return # Redundant registrations are benign ! if key in extension_registry: raise ValueError("key %s is already registered with code %s" % ! (key, extension_registry[key])) ! if code in inverted_registry: raise ValueError("code %s is already in use for key %s" % ! (code, inverted_registry[code])) ! extension_registry[key] = code ! inverted_registry[code] = key def remove_extension(module, name, code): """Unregister an extension code. For testing only.""" key = (module, name) ! if (extension_registry.get(key) != code or ! inverted_registry.get(code) != key): raise ValueError("key %s is not registered with code %s" % (key, code)) ! del extension_registry[key] ! del inverted_registry[code] ! if code in extension_cache: ! del extension_cache[code] def clear_extension_cache(): ! extension_cache.clear() # Standard extension code assignments --- 91,120 ---- raise ValueError, "code out of range" key = (module, name) ! if (_extension_registry.get(key) == code and ! _inverted_registry.get(code) == key): return # Redundant registrations are benign ! if key in _extension_registry: raise ValueError("key %s is already registered with code %s" % ! (key, _extension_registry[key])) ! if code in _inverted_registry: raise ValueError("code %s is already in use for key %s" % ! (code, _inverted_registry[code])) ! _extension_registry[key] = code ! _inverted_registry[code] = key def remove_extension(module, name, code): """Unregister an extension code. For testing only.""" key = (module, name) ! if (_extension_registry.get(key) != code or ! _inverted_registry.get(code) != key): raise ValueError("key %s is not registered with code %s" % (key, code)) ! del _extension_registry[key] ! del _inverted_registry[code] ! if code in _extension_cache: ! del _extension_cache[code] def clear_extension_cache(): ! _extension_cache.clear() # Standard extension code assignments From gvanrossum@users.sourceforge.net Tue Feb 4 01:54:52 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 03 Feb 2003 17:54:52 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.120,2.121 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv3141/Modules Modified Files: cPickle.c Log Message: Rename the extension registry variables to have leading underscores -- this clarifies that they are part of an internal API (albeit shared between pickle.py, copy_reg.py and cPickle.c). I'd like to do the same for copy_reg.dispatch_table, but worry that it might be used by existing code. This risk doesn't exist for the extension registry. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.120 retrieving revision 2.121 diff -C2 -d -r2.120 -r2.121 *** cPickle.c 4 Feb 2003 00:30:46 -0000 2.120 --- cPickle.c 4 Feb 2003 01:54:49 -0000 2.121 *************** *** 103,111 **** /* For EXT[124] opcodes. */ ! /* copy_reg.extension_registry, {(module_name, function_name): code} */ static PyObject *extension_registry; ! /* copy_reg.inverted_registry, {code: (module_name, function_name)} */ static PyObject *inverted_registry; ! /* copy_reg.extension_cache, {code: object} */ static PyObject *extension_cache; --- 103,111 ---- /* For EXT[124] opcodes. */ ! /* copy_reg._extension_registry, {(module_name, function_name): code} */ static PyObject *extension_registry; ! /* copy_reg._inverted_registry, {code: (module_name, function_name)} */ static PyObject *inverted_registry; ! /* copy_reg._extension_cache, {code: object} */ static PyObject *extension_cache; *************** *** 5093,5105 **** extension_registry = PyObject_GetAttrString(copy_reg, ! "extension_registry"); if (!extension_registry) return -1; inverted_registry = PyObject_GetAttrString(copy_reg, ! "inverted_registry"); if (!inverted_registry) return -1; extension_cache = PyObject_GetAttrString(copy_reg, ! "extension_cache"); if (!extension_cache) return -1; --- 5093,5105 ---- extension_registry = PyObject_GetAttrString(copy_reg, ! "_extension_registry"); if (!extension_registry) return -1; inverted_registry = PyObject_GetAttrString(copy_reg, ! "_inverted_registry"); if (!inverted_registry) return -1; extension_cache = PyObject_GetAttrString(copy_reg, ! "_extension_cache"); if (!extension_cache) return -1; From tim@zope.com Tue Feb 4 02:16:15 2003 From: tim@zope.com (Tim Peters) Date: Mon, 3 Feb 2003 21:16:15 -0500 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.143,1.144 copy_reg.py,1.14,1.15 In-Reply-To: Message-ID: > Rename the extension registry variables to have leading underscores -- > this clarifies that they are part of an internal API (albeit shared > between pickle.py, copy_reg.py and cPickle.c). Good idea! > I'd like to do the same for copy_reg.dispatch_table, but worry that it > might be used by existing code. Zope3's src/zodb/code/patch.py imports dispatch_table (as well as being the only known caller of pickle.Pickler.save_empty_tuple()). We should quiz Jeremy about why he needs to cheat so badly here <0.5 wink>. From tim_one@users.sourceforge.net Tue Feb 4 05:06:19 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 03 Feb 2003 21:06:19 -0800 Subject: [Python-checkins] python/dist/src/Lib copy_reg.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv29814/Lib Modified Files: copy_reg.py Log Message: cPickle can load pickles using proto 2 EXT[124] now, but can't yet generate these opcodes. Index: copy_reg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy_reg.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** copy_reg.py 4 Feb 2003 01:54:49 -0000 1.15 --- copy_reg.py 4 Feb 2003 05:06:17 -0000 1.16 *************** *** 88,92 **** """Register an extension code.""" code = int(code) ! if not 1 <= code < 0x7fffffff: raise ValueError, "code out of range" key = (module, name) --- 88,92 ---- """Register an extension code.""" code = int(code) ! if not 1 <= code <= 0x7fffffff: raise ValueError, "code out of range" key = (module, name) From tim_one@users.sourceforge.net Tue Feb 4 05:06:20 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 03 Feb 2003 21:06:20 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.121,2.122 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv29814/Modules Modified Files: cPickle.c Log Message: cPickle can load pickles using proto 2 EXT[124] now, but can't yet generate these opcodes. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.121 retrieving revision 2.122 diff -C2 -d -r2.121 -r2.122 *** cPickle.c 4 Feb 2003 01:54:49 -0000 2.121 --- cPickle.c 4 Feb 2003 05:06:17 -0000 2.122 *************** *** 3734,3737 **** --- 3734,3805 ---- } + /* Push an object from the extension registry (EXT[124]). nbytes is + * the number of bytes following the opcode, holding the index (code) value. + */ + static int + load_extension(Unpicklerobject *self, int nbytes) + { + char *codebytes; /* the nbytes bytes after the opcode */ + long code; /* calc_binint returns long */ + PyObject *py_code; /* code as a Python int */ + PyObject *obj; /* the object to push */ + PyObject *pair; /* (module_name, class_name) */ + PyObject *module_name, *class_name; + + assert(nbytes == 1 || nbytes == 2 || nbytes == 4); + if (self->read_func(self, &codebytes, nbytes) < 0) return -1; + code = calc_binint(codebytes, nbytes); + if (code <= 0) { /* note that 0 is forbidden */ + /* Corrupt or hostile pickle. */ + PyErr_SetString(UnpicklingError, "EXT specifies code <= 0"); + return -1; + } + + /* Look for the code in the cache. */ + py_code = PyInt_FromLong(code); + if (py_code == NULL) return -1; + obj = PyDict_GetItem(extension_cache, py_code); + if (obj != NULL) { + /* Bingo. */ + Py_DECREF(py_code); + PDATA_APPEND(self->stack, obj, -1); + return 0; + } + + /* Look up the (module_name, class_name) pair. */ + pair = PyDict_GetItem(inverted_registry, py_code); + if (pair == NULL) { + Py_DECREF(py_code); + PyErr_Format(PyExc_ValueError, "unregistered extension " + "code %ld", code); + return -1; + } + /* Since the extension registry is manipulable via Python code, + * confirm that obj is really a 2-tuple of strings. + */ + if (!PyTuple_Check(pair) || PyTuple_Size(pair) != 2 || + !PyString_Check(module_name = PyTuple_GET_ITEM(pair, 0)) || + !PyString_Check(class_name = PyTuple_GET_ITEM(pair, 1))) { + Py_DECREF(py_code); + PyErr_Format(PyExc_ValueError, "_inverted_registry[%ld] " + "isn't a 2-tuple of strings", code); + return -1; + } + /* Load the object. */ + obj = find_class(module_name, class_name, self->find_class); + if (obj == NULL) { + Py_DECREF(py_code); + return -1; + } + /* Cache code -> obj. */ + code = PyDict_SetItem(extension_cache, py_code, obj); + Py_DECREF(py_code); + if (code < 0) { + Py_DECREF(obj); + return -1; + } + PDATA_PUSH(self->stack, obj, -1); + return 0; + } static int *************** *** 4215,4218 **** --- 4283,4300 ---- continue; + case EXT1: + if (load_extension(self, 1) < 0) + break; + continue; + + case EXT2: + if (load_extension(self, 2) < 0) + break; + continue; + + case EXT4: + if (load_extension(self, 4) < 0) + break; + continue; case MARK: if (load_mark(self) < 0) *************** *** 4371,4374 **** --- 4453,4467 ---- } + static int + noload_extension(Unpicklerobject *self, int nbytes) + { + char *codebytes; + + assert(nbytes == 1 || nbytes == 2 || nbytes == 4); + if (self->read_func(self, &codebytes, nbytes) < 0) return -1; + PDATA_APPEND(self->stack, Py_None, -1); + return 0; + } + static PyObject * *************** *** 4555,4558 **** --- 4648,4666 ---- case GET: if (load_get(self) < 0) + break; + continue; + + case EXT1: + if (noload_extension(self, 1) < 0) + break; + continue; + + case EXT2: + if (noload_extension(self, 2) < 0) + break; + continue; + + case EXT4: + if (noload_extension(self, 4) < 0) break; continue; From tim_one@users.sourceforge.net Tue Feb 4 05:20:34 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 03 Feb 2003 21:20:34 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.122,2.123 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv2303/Modules Modified Files: cPickle.c Log Message: Typo in comment. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.122 retrieving revision 2.123 diff -C2 -d -r2.122 -r2.123 *** cPickle.c 4 Feb 2003 05:06:17 -0000 2.122 --- cPickle.c 4 Feb 2003 05:20:32 -0000 2.123 *************** *** 3776,3780 **** } /* Since the extension registry is manipulable via Python code, ! * confirm that obj is really a 2-tuple of strings. */ if (!PyTuple_Check(pair) || PyTuple_Size(pair) != 2 || --- 3776,3780 ---- } /* Since the extension registry is manipulable via Python code, ! * confirm that pair is really a 2-tuple of strings. */ if (!PyTuple_Check(pair) || PyTuple_Size(pair) != 2 || From rhettinger@users.sourceforge.net Tue Feb 4 05:47:33 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 03 Feb 2003 21:47:33 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_random.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv11766 Modified Files: test_random.py Log Message: Add refcount test. Index: test_random.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_random.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_random.py 17 Jan 2003 17:23:23 -0000 1.7 --- test_random.py 4 Feb 2003 05:47:30 -0000 1.8 *************** *** 75,79 **** trials = 10000 # large num prevents false negatives without slowing normal case def factorial(n): ! return n==0 and 1 or n * factorial(n-1) for k in xrange(n): expected = factorial(n) / factorial(n-k) --- 75,79 ---- trials = 10000 # large num prevents false negatives without slowing normal case def factorial(n): ! return reduce(int.__mul__, xrange(1, n), 1) for k in xrange(n): expected = factorial(n) / factorial(n-k) *************** *** 272,276 **** self.failUnless(Set(random.__all__) <= Set(dir(random))) ! def test_main(): suite = unittest.TestSuite() for testclass in (WichmannHill_TestBasicOps, --- 272,276 ---- self.failUnless(Set(random.__all__) <= Set(dir(random))) ! def test_main(verbose=None): suite = unittest.TestSuite() for testclass in (WichmannHill_TestBasicOps, *************** *** 281,284 **** test_support.run_suite(suite) if __name__ == "__main__": ! test_main() --- 281,293 ---- test_support.run_suite(suite) + # verify reference counting + import sys + if verbose and hasattr(sys, "gettotalrefcount"): + counts = [] + for i in xrange(5): + test_support.run_suite(suite) + counts.append(sys.gettotalrefcount()-i) + print counts + if __name__ == "__main__": ! test_main(verbose=True) From gvanrossum@users.sourceforge.net Tue Feb 4 14:50:26 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 04 Feb 2003 06:50:26 -0800 Subject: [Python-checkins] python/nondist/peps pep-0307.txt,1.7,1.8 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv13853 Modified Files: pep-0307.txt Log Message: Fix crucial typo found by Niki Spahiev. Index: pep-0307.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0307.txt,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** pep-0307.txt 3 Feb 2003 20:22:23 -0000 1.7 --- pep-0307.txt 4 Feb 2003 14:50:23 -0000 1.8 *************** *** 262,266 **** When __reduce__ exists, __getstate__ is not called (unless your ! __reduce__ implementation calls it), but __getstate__ will be called with the third item from the tuple returned by __reduce__, if not None. --- 262,266 ---- When __reduce__ exists, __getstate__ is not called (unless your ! __reduce__ implementation calls it), but __setstate__ will be called with the third item from the tuple returned by __reduce__, if not None. From montanaro@users.sourceforge.net Tue Feb 4 14:54:56 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Tue, 04 Feb 2003 06:54:56 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.12,1.13 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv16326 Modified Files: _csv.c Log Message: memory allocated with PyMem_Malloc needs to be freed with PyMem_Free Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** _csv.c 3 Feb 2003 02:43:08 -0000 1.12 --- _csv.c 4 Feb 2003 14:54:54 -0000 1.13 *************** *** 517,521 **** self->rec = PyMem_Realloc(self->rec, self->rec_size); if (self->rec == NULL) ! free(old_rec); } if (self->rec == NULL) { --- 517,521 ---- self->rec = PyMem_Realloc(self->rec, self->rec_size); if (self->rec == NULL) ! PyMem_Free(old_rec); } if (self->rec == NULL) { *************** *** 645,654 **** { if (self->field) ! free(self->field); Py_XDECREF(self->fields); Py_XDECREF(self->lineterminator); if (self->rec) ! free(self->rec); PyMem_DEL(self); --- 645,654 ---- { if (self->field) ! PyMem_Free(self->field); Py_XDECREF(self->fields); Py_XDECREF(self->lineterminator); if (self->rec) ! PyMem_Free(self->rec); PyMem_DEL(self); From fdrake@users.sourceforge.net Tue Feb 4 15:01:40 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Tue, 04 Feb 2003 07:01:40 -0800 Subject: [Python-checkins] python/dist/src/Doc/perl python.perl,1.132,1.133 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/perl In directory sc8-pr-cvs1:/tmp/cvs-serv20576 Modified Files: python.perl Log Message: Twiddle. Index: python.perl =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/perl/python.perl,v retrieving revision 1.132 retrieving revision 1.133 diff -C2 -d -r1.132 -r1.133 *** python.perl 15 Nov 2002 19:04:10 -0000 1.132 --- python.perl 4 Feb 2003 15:01:37 -0000 1.133 *************** *** 102,106 **** sub do_cmd_ABC{ 'ABC' . $_[0]; } ! sub do_cmd_UNIX{ 'Unix'. $_[0]; } sub do_cmd_ASCII{ 'ASCII' . $_[0]; } sub do_cmd_POSIX{ 'POSIX' . $_[0]; } --- 102,107 ---- sub do_cmd_ABC{ 'ABC' . $_[0]; } ! sub do_cmd_UNIX{ 'Unix' ! . $_[0]; } sub do_cmd_ASCII{ 'ASCII' . $_[0]; } sub do_cmd_POSIX{ 'POSIX' . $_[0]; } From fdrake@users.sourceforge.net Tue Feb 4 15:12:09 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Tue, 04 Feb 2003 07:12:09 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libtime.tex,1.54,1.55 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv27179 Modified Files: libtime.tex Log Message: Update to better reflect the usage of struct_time instances throughout; continuing to call these "time tuples" is misleading at best. Closes SF bug #671731; will backport to 2.2.x. Index: libtime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtime.tex,v retrieving revision 1.54 retrieving revision 1.55 diff -C2 -d -r1.54 -r1.55 *** libtime.tex 31 Dec 2002 04:41:38 -0000 1.54 --- libtime.tex 4 Feb 2003 15:12:06 -0000 1.55 *************** *** 30,39 **** depends on the platform's C library, which generally doesn't have year 2000 issues, since all dates and times are represented internally as ! seconds since the epoch. Functions accepting a time tuple (see below) ! generally require a 4-digit year. For backward compatibility, 2-digit ! years are supported if the module variable \code{accept2dyear} is a ! non-zero integer; this variable is initialized to \code{1} unless the ! environment variable \envvar{PYTHONY2K} is set to a non-empty string, ! in which case it is initialized to \code{0}. Thus, you can set \envvar{PYTHONY2K} to a non-empty string in the environment to require 4-digit years for all year input. When 2-digit years are accepted, they are --- 30,40 ---- depends on the platform's C library, which generally doesn't have year 2000 issues, since all dates and times are represented internally as ! seconds since the epoch. Functions accepting a \class{struct_time} ! (see below) generally require a 4-digit year. For backward ! compatibility, 2-digit years are supported if the module variable ! \code{accept2dyear} is a non-zero integer; this variable is ! initialized to \code{1} unless the environment variable ! \envvar{PYTHONY2K} is set to a non-empty string, in which case it is ! initialized to \code{0}. Thus, you can set \envvar{PYTHONY2K} to a non-empty string in the environment to require 4-digit years for all year input. When 2-digit years are accepted, they are *************** *** 100,108 **** When a tuple with an incorrect length is passed to a function ! expecting a time tuple, or having elements of the wrong type, a \exception{TypeError} is raised. \versionchanged[The time value sequence was changed from a tuple to a ! specialized type, with the addition of attribute names for the fields]{2.2} \end{itemize} --- 101,109 ---- When a tuple with an incorrect length is passed to a function ! expecting a \class{struct_time}, or having elements of the wrong type, a \exception{TypeError} is raised. \versionchanged[The time value sequence was changed from a tuple to a ! \class{struct_time}, with the addition of attribute names for the fields]{2.2} \end{itemize} *************** *** 125,137 **** \end{datadesc} ! \begin{funcdesc}{asctime}{\optional{tuple}} ! Convert a tuple representing a time as returned by \function{gmtime()} or \function{localtime()} to a 24-character string of the following form: ! \code{'Sun Jun 20 23:21:05 1993'}. If \var{tuple} is not provided, the current time as returned by \function{localtime()} is used. Locale information is not used by \function{asctime()}. \note{Unlike the C function of the same name, there is no trailing newline.} ! \versionchanged[Allowed \var{tuple} to be omitted]{2.1} \end{funcdesc} --- 126,139 ---- \end{datadesc} ! \begin{funcdesc}{asctime}{\optional{t}} ! Convert a tuple or \class{struct_time} representing a time as returned ! by \function{gmtime()} or \function{localtime()} to a 24-character string of the following form: ! \code{'Sun Jun 20 23:21:05 1993'}. If \var{t} is not provided, the current time as returned by \function{localtime()} is used. Locale information is not used by \function{asctime()}. \note{Unlike the C function of the same name, there is no trailing newline.} ! \versionchanged[Allowed \var{t} to be omitted]{2.1} \end{funcdesc} *************** *** 165,173 **** \begin{funcdesc}{gmtime}{\optional{secs}} ! Convert a time expressed in seconds since the epoch to a time tuple in UTC in which the dst flag is always zero. If \var{secs} is not provided, the current time as returned by \function{time()} is used. Fractions of a second are ignored. See above for a description of the ! tuple lay-out. \versionchanged[Allowed \var{secs} to be omitted]{2.1} \end{funcdesc} --- 167,175 ---- \begin{funcdesc}{gmtime}{\optional{secs}} ! Convert a time expressed in seconds since the epoch to a \class{struct_time} in UTC in which the dst flag is always zero. If \var{secs} is not provided, the current time as returned by \function{time()} is used. Fractions of a second are ignored. See above for a description of the ! \class{struct_time} object. \versionchanged[Allowed \var{secs} to be omitted]{2.1} \end{funcdesc} *************** *** 179,186 **** \end{funcdesc} ! \begin{funcdesc}{mktime}{tuple} This is the inverse function of \function{localtime()}. Its argument ! is the full 9-tuple (since the dst flag is needed; use \code{-1} as ! the dst flag if it is unknown) which expresses the time in \emph{local} time, not UTC. It returns a floating point number, for compatibility with \function{time()}. If the input value cannot be --- 181,189 ---- \end{funcdesc} ! \begin{funcdesc}{mktime}{t} This is the inverse function of \function{localtime()}. Its argument ! is the \class{struct_time} or full 9-tuple (since the dst flag is ! needed; use \code{-1} as the dst flag if it is unknown) which ! expresses the time in \emph{local} time, not UTC. It returns a floating point number, for compatibility with \function{time()}. If the input value cannot be *************** *** 201,210 **** \end{funcdesc} ! \begin{funcdesc}{strftime}{format\optional{, tuple}} ! Convert a tuple representing a time as returned by \function{gmtime()} ! or \function{localtime()} to a string as specified by the \var{format} ! argument. If \var{tuple} is not provided, the current time as returned by ! \function{localtime()} is used. \var{format} must be a string. ! \versionchanged[Allowed \var{tuple} to be omitted]{2.1} The following directives can be embedded in the \var{format} string. --- 204,214 ---- \end{funcdesc} ! \begin{funcdesc}{strftime}{format\optional{, t}} ! Convert a tuple or \class{struct_time} representing a time as returned ! by \function{gmtime()} or \function{localtime()} to a string as ! specified by the \var{format} argument. If \var{t} is not ! provided, the current time as returned by \function{localtime()} is ! used. \var{format} must be a string. ! \versionchanged[Allowed \var{t} to be omitted]{2.1} The following directives can be embedded in the \var{format} string. *************** *** 278,282 **** \begin{funcdesc}{strptime}{string\optional{, format}} Parse a string representing a time according to a format. The return ! value is a tuple as returned by \function{gmtime()} or \function{localtime()}. The \var{format} parameter uses the same directives as those used by \function{strftime()}; it defaults to --- 282,286 ---- \begin{funcdesc}{strptime}{string\optional{, format}} Parse a string representing a time according to a format. The return ! value is a \class{struct_time} as returned by \function{gmtime()} or \function{localtime()}. The \var{format} parameter uses the same directives as those used by \function{strftime()}; it defaults to From fdrake@users.sourceforge.net Tue Feb 4 15:13:27 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Tue, 04 Feb 2003 07:13:27 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libtime.tex,1.48.6.3,1.48.6.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv27806 Modified Files: Tag: release22-maint libtime.tex Log Message: Update to better reflect the usage of struct_time instances throughout; continuing to call these "time tuples" is misleading at best. Closes SF bug #671731; backported from rev 1.55. Index: libtime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtime.tex,v retrieving revision 1.48.6.3 retrieving revision 1.48.6.4 diff -C2 -d -r1.48.6.3 -r1.48.6.4 *** libtime.tex 15 Nov 2002 23:01:37 -0000 1.48.6.3 --- libtime.tex 4 Feb 2003 15:13:25 -0000 1.48.6.4 *************** *** 30,39 **** depends on the platform's C library, which generally doesn't have year 2000 issues, since all dates and times are represented internally as ! seconds since the epoch. Functions accepting a time tuple (see below) ! generally require a 4-digit year. For backward compatibility, 2-digit ! years are supported if the module variable \code{accept2dyear} is a ! non-zero integer; this variable is initialized to \code{1} unless the ! environment variable \envvar{PYTHONY2K} is set to a non-empty string, ! in which case it is initialized to \code{0}. Thus, you can set \envvar{PYTHONY2K} to a non-empty string in the environment to require 4-digit years for all year input. When 2-digit years are accepted, they are --- 30,40 ---- depends on the platform's C library, which generally doesn't have year 2000 issues, since all dates and times are represented internally as ! seconds since the epoch. Functions accepting a \class{struct_time} ! (see below) generally require a 4-digit year. For backward ! compatibility, 2-digit years are supported if the module variable ! \code{accept2dyear} is a non-zero integer; this variable is ! initialized to \code{1} unless the environment variable ! \envvar{PYTHONY2K} is set to a non-empty string, in which case it is ! initialized to \code{0}. Thus, you can set \envvar{PYTHONY2K} to a non-empty string in the environment to require 4-digit years for all year input. When 2-digit years are accepted, they are *************** *** 100,108 **** When a tuple with an incorrect length is passed to a function ! expecting a time tuple, or having elements of the wrong type, a \exception{TypeError} is raised. \versionchanged[The time value sequence was changed from a tuple to a ! specialized type, with the addition of attribute names for the fields]{2.2} \end{itemize} --- 101,109 ---- When a tuple with an incorrect length is passed to a function ! expecting a \class{struct_time}, or having elements of the wrong type, a \exception{TypeError} is raised. \versionchanged[The time value sequence was changed from a tuple to a ! \class{struct_time}, with the addition of attribute names for the fields]{2.2} \end{itemize} *************** *** 125,137 **** \end{datadesc} ! \begin{funcdesc}{asctime}{\optional{tuple}} ! Convert a tuple representing a time as returned by \function{gmtime()} or \function{localtime()} to a 24-character string of the following form: ! \code{'Sun Jun 20 23:21:05 1993'}. If \var{tuple} is not provided, the current time as returned by \function{localtime()} is used. Locale information is not used by \function{asctime()}. \note{Unlike the C function of the same name, there is no trailing newline.} ! \versionchanged[Allowed \var{tuple} to be omitted]{2.1} \end{funcdesc} --- 126,139 ---- \end{datadesc} ! \begin{funcdesc}{asctime}{\optional{t}} ! Convert a tuple or \class{struct_time} representing a time as returned ! by \function{gmtime()} or \function{localtime()} to a 24-character string of the following form: ! \code{'Sun Jun 20 23:21:05 1993'}. If \var{t} is not provided, the current time as returned by \function{localtime()} is used. Locale information is not used by \function{asctime()}. \note{Unlike the C function of the same name, there is no trailing newline.} ! \versionchanged[Allowed \var{t} to be omitted]{2.1} \end{funcdesc} *************** *** 165,173 **** \begin{funcdesc}{gmtime}{\optional{secs}} ! Convert a time expressed in seconds since the epoch to a time tuple in UTC in which the dst flag is always zero. If \var{secs} is not provided, the current time as returned by \function{time()} is used. Fractions of a second are ignored. See above for a description of the ! tuple lay-out. \versionchanged[Allowed \var{secs} to be omitted]{2.1} \end{funcdesc} --- 167,175 ---- \begin{funcdesc}{gmtime}{\optional{secs}} ! Convert a time expressed in seconds since the epoch to a \class{struct_time} in UTC in which the dst flag is always zero. If \var{secs} is not provided, the current time as returned by \function{time()} is used. Fractions of a second are ignored. See above for a description of the ! \class{struct_time} object. \versionchanged[Allowed \var{secs} to be omitted]{2.1} \end{funcdesc} *************** *** 179,186 **** \end{funcdesc} ! \begin{funcdesc}{mktime}{tuple} This is the inverse function of \function{localtime()}. Its argument ! is the full 9-tuple (since the dst flag is needed; use \code{-1} as ! the dst flag if it is unknown) which expresses the time in \emph{local} time, not UTC. It returns a floating point number, for compatibility with \function{time()}. If the input value cannot be --- 181,189 ---- \end{funcdesc} ! \begin{funcdesc}{mktime}{t} This is the inverse function of \function{localtime()}. Its argument ! is the \class{struct_time} or full 9-tuple (since the dst flag is ! needed; use \code{-1} as the dst flag if it is unknown) which ! expresses the time in \emph{local} time, not UTC. It returns a floating point number, for compatibility with \function{time()}. If the input value cannot be *************** *** 201,210 **** \end{funcdesc} ! \begin{funcdesc}{strftime}{format\optional{, tuple}} ! Convert a tuple representing a time as returned by \function{gmtime()} ! or \function{localtime()} to a string as specified by the \var{format} ! argument. If \var{tuple} is not provided, the current time as returned by ! \function{localtime()} is used. \var{format} must be a string. ! \versionchanged[Allowed \var{tuple} to be omitted]{2.1} The following directives can be embedded in the \var{format} string. --- 204,214 ---- \end{funcdesc} ! \begin{funcdesc}{strftime}{format\optional{, t}} ! Convert a tuple or \class{struct_time} representing a time as returned ! by \function{gmtime()} or \function{localtime()} to a string as ! specified by the \var{format} argument. If \var{t} is not ! provided, the current time as returned by \function{localtime()} is ! used. \var{format} must be a string. ! \versionchanged[Allowed \var{t} to be omitted]{2.1} The following directives can be embedded in the \var{format} string. *************** *** 278,282 **** \begin{funcdesc}{strptime}{string\optional{, format}} Parse a string representing a time according to a format. The return ! value is a tuple as returned by \function{gmtime()} or \function{localtime()}. The \var{format} parameter uses the same directives as those used by \function{strftime()}; it defaults to --- 282,286 ---- \begin{funcdesc}{strptime}{string\optional{, format}} Parse a string representing a time according to a format. The return ! value is a \class{struct_time} as returned by \function{gmtime()} or \function{localtime()}. The \var{format} parameter uses the same directives as those used by \function{strftime()}; it defaults to From jackjansen@users.sourceforge.net Tue Feb 4 15:35:09 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 04 Feb 2003 07:35:09 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules/qt _Qtmodule.c,1.14,1.15 qtscan.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/qt In directory sc8-pr-cvs1:/tmp/cvs-serv7139 Modified Files: _Qtmodule.c qtscan.py Log Message: Changed an edit instruction because of a changed parameter name (sigh). Index: _Qtmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qt/_Qtmodule.c,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** _Qtmodule.c 23 Dec 2002 23:16:24 -0000 1.14 --- _Qtmodule.c 4 Feb 2003 15:35:06 -0000 1.15 *************** *** 15,21 **** /* Macro to test whether a weak-loaded CFM function exists */ #define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\ ! PyErr_SetString(PyExc_NotImplementedError, \ ! "Not available in this shared library/OS version"); \ ! return NULL; \ }} while(0) --- 15,21 ---- /* Macro to test whether a weak-loaded CFM function exists */ #define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\ ! PyErr_SetString(PyExc_NotImplementedError, \ ! "Not available in this shared library/OS version"); \ ! return NULL; \ }} while(0) *************** *** 9341,9345 **** PyMac_PRECHECK(ConvertTime); #endif ! if (!PyArg_ParseTuple(_args, "O&", TimeBaseObj_Convert, &newBase)) return NULL; --- 9341,9346 ---- PyMac_PRECHECK(ConvertTime); #endif ! if (!PyArg_ParseTuple(_args, "O&O&", ! QtTimeRecord_Convert, &theTime, TimeBaseObj_Convert, &newBase)) return NULL; *************** *** 9359,9363 **** PyMac_PRECHECK(ConvertTimeScale); #endif ! if (!PyArg_ParseTuple(_args, "l", &newScale)) return NULL; --- 9360,9365 ---- PyMac_PRECHECK(ConvertTimeScale); #endif ! if (!PyArg_ParseTuple(_args, "O&l", ! QtTimeRecord_Convert, &theTime, &newScale)) return NULL; *************** *** 9692,9698 **** PyDoc_STR("() -> (TimeBase _rv)")}, {"ConvertTime", (PyCFunction)Qt_ConvertTime, 1, ! PyDoc_STR("(TimeBase newBase) -> (TimeRecord theTime)")}, {"ConvertTimeScale", (PyCFunction)Qt_ConvertTimeScale, 1, ! PyDoc_STR("(TimeScale newScale) -> (TimeRecord theTime)")}, {"AddTime", (PyCFunction)Qt_AddTime, 1, PyDoc_STR("(TimeRecord dst, TimeRecord src) -> (TimeRecord dst)")}, --- 9694,9700 ---- PyDoc_STR("() -> (TimeBase _rv)")}, {"ConvertTime", (PyCFunction)Qt_ConvertTime, 1, ! PyDoc_STR("(TimeRecord theTime, TimeBase newBase) -> (TimeRecord theTime)")}, {"ConvertTimeScale", (PyCFunction)Qt_ConvertTimeScale, 1, ! PyDoc_STR("(TimeRecord theTime, TimeScale newScale) -> (TimeRecord theTime)")}, {"AddTime", (PyCFunction)Qt_AddTime, 1, PyDoc_STR("(TimeRecord dst, TimeRecord src) -> (TimeRecord dst)")}, Index: qtscan.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qt/qtscan.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** qtscan.py 12 Dec 2002 10:31:52 -0000 1.21 --- qtscan.py 4 Feb 2003 15:35:07 -0000 1.22 *************** *** 140,143 **** --- 140,144 ---- # ConvertTime and ConvertTimeScale ([('TimeRecord', 'inout', 'OutMode')], [('TimeRecord', 'inout', 'InOutMode')]), + ([('TimeRecord', 'theTime', 'OutMode')], [('TimeRecord', 'theTime', 'InOutMode')]), # AddTime and SubtractTime From jackjansen@users.sourceforge.net Tue Feb 4 15:36:46 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 04 Feb 2003 07:36:46 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac videoreader.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv7687 Modified Files: videoreader.py Log Message: - Handle the img and MediaFormat modules not being available (by not providing the format info, only the raw data). - Get rid of fsspecs. - Make the demo program at least do something if img not available. Index: videoreader.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/videoreader.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** videoreader.py 30 Dec 2002 22:04:20 -0000 1.1 --- videoreader.py 4 Feb 2003 15:36:42 -0000 1.2 *************** *** 13,21 **** from Carbon import QDOffscreen from Carbon import Res ! import MediaDescr ! import imgformat import os # import audio.format - import macfs class VideoFormat: --- 13,30 ---- from Carbon import QDOffscreen from Carbon import Res ! try: ! import MediaDescr ! except ImportError: ! def _audiodescr(data): ! return None ! else: ! def _audiodescr(data): ! return MediaDescr.SoundDescription.decode(data) ! try: ! from imgformat import macrgb ! except ImportError: ! macrgb = "Macintosh RGB format" import os # import audio.format class VideoFormat: *************** *** 41,46 **** class _Reader: def __init__(self, path): ! fsspec = macfs.FSSpec(path) ! fd = Qt.OpenMovieFile(fsspec, 0) self.movie, d1, d2 = Qt.NewMovieFromFile(fd, 0, 0) self.movietimescale = self.movie.GetMovieTimeScale() --- 50,54 ---- class _Reader: def __init__(self, path): ! fd = Qt.OpenMovieFile(path, 0) self.movie, d1, d2 = Qt.NewMovieFromFile(fd, 0, 0) self.movietimescale = self.movie.GetMovieTimeScale() *************** *** 56,60 **** n = self.audiomedia.GetMediaSampleDescriptionCount() self.audiomedia.GetMediaSampleDescription(1, handle) ! self.audiodescr = MediaDescr.SoundDescription.decode(handle.data) self.audiotimescale = self.audiomedia.GetMediaTimeScale() del handle --- 64,68 ---- n = self.audiomedia.GetMediaSampleDescriptionCount() self.audiomedia.GetMediaSampleDescription(1, handle) ! self.audiodescr = _audiodescr(handle.data) self.audiotimescale = self.audiomedia.GetMediaTimeScale() del handle *************** *** 140,143 **** --- 148,153 ---- def GetAudioFormat(self): + if not self.audiodescr: + return None, None, None, None, None bps = self.audiodescr['sampleSize'] nch = self.audiodescr['numChannels'] *************** *** 168,171 **** --- 178,183 ---- def GetAudioFrameRate(self): + if not self.audiodescr: + return None return int(self.audiodescr['sampleRate']) *************** *** 173,177 **** width = self.videodescr['width'] height = self.videodescr['height'] ! return VideoFormat('dummy_format', 'Dummy Video Format', width, height, imgformat.macrgb) def GetVideoFrameRate(self): --- 185,189 ---- width = self.videodescr['width'] height = self.videodescr['height'] ! return VideoFormat('dummy_format', 'Dummy Video Format', width, height, macrgb) def GetVideoFrameRate(self): *************** *** 237,252 **** def _test(): ! import img import MacOS Qt.EnterMovies() ! fss, ok = macfs.PromptGetFile('Video to convert') ! if not ok: sys.exit(0) ! path = fss.as_pathname() rdr = reader(path) if not rdr: sys.exit(1) ! dstfss, ok = macfs.StandardPutFile('Name for output folder') ! if not ok: sys.exit(0) ! dstdir = dstfss.as_pathname() num = 0 os.mkdir(dstdir) --- 249,266 ---- def _test(): ! import EasyDialogs ! try: ! import img ! except ImportError: ! img = None import MacOS Qt.EnterMovies() ! path = EasyDialogs.AskFileForOpen(message='Video to convert') ! if not path: sys.exit(0) rdr = reader(path) if not rdr: sys.exit(1) ! dstdir = EasyDialogs.AskFileForSave(message='Name for output folder') ! if not dstdir: sys.exit(0) num = 0 os.mkdir(dstdir) *************** *** 259,272 **** num = num+1 pname = os.path.join(dstdir, fname) ! print 'Writing', fname, imgw, imgh, len(data) ! wrt = img.writer(imgfmt, pname) ! wrt.width = imgw ! wrt.height = imgh ! wrt.write(data) ! timestamp, data = rdr.ReadVideo() ! MacOS.SetCreatorAndType(pname, 'ogle', 'JPEG') ! if num > 20: ! print 'stopping at 20 frames so your disk does not fill up:-)' ! break print 'Total frames:', num --- 273,288 ---- num = num+1 pname = os.path.join(dstdir, fname) ! if not img: print 'Not', ! print 'Writing %s, size %dx%d, %d bytes'%(fname, imgw, imgh, len(data)) ! if img: ! wrt = img.writer(imgfmt, pname) ! wrt.width = imgw ! wrt.height = imgh ! wrt.write(data) ! timestamp, data = rdr.ReadVideo() ! MacOS.SetCreatorAndType(pname, 'ogle', 'JPEG') ! if num > 20: ! print 'stopping at 20 frames so your disk does not fill up:-)' ! break print 'Total frames:', num From doerwalter@users.sourceforge.net Tue Feb 4 16:28:02 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue, 04 Feb 2003 08:28:02 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_builtin.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv5503/Lib/test Modified Files: test_builtin.py Log Message: filterstring() and filterunicode() in Python/bltinmodule.c blindly assumed that tp_as_sequence->sq_item always returns a str or unicode object. This might fail with str or unicode subclasses. This patch checks whether the object returned from __getitem__ is a str/unicode object and raises a TypeError if not (and the filter function returned true). Furthermore the result for __getitem__ can be more than one character long, so checks for enough memory have to be done. Index: test_builtin.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_builtin.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_builtin.py 28 Jan 2003 19:21:18 -0000 1.6 --- test_builtin.py 4 Feb 2003 16:28:00 -0000 1.7 *************** *** 368,371 **** --- 368,381 ---- self.assertRaises(ValueError, filter, lambda x: x >="3", badstr("1234")) + class badstr2(str): + def __getitem__(self, index): + return 42 + self.assertRaises(TypeError, filter, lambda x: x >=42, badstr2("1234")) + + class weirdstr(str): + def __getitem__(self, index): + return weirdstr(2*str.__getitem__(self, index)) + self.assertEqual(filter(lambda x: x>="33", weirdstr("1234")), "3344") + if have_unicode: # test bltinmodule.c::filterunicode() *************** *** 374,377 **** --- 384,398 ---- self.assertRaises(TypeError, filter, 42, unicode("12")) self.assertRaises(ValueError, filter, lambda x: x >="3", badstr(unicode("1234"))) + + class badunicode(unicode): + def __getitem__(self, index): + return 42 + self.assertRaises(TypeError, filter, lambda x: x >=42, badunicode("1234")) + + class weirdunicode(unicode): + def __getitem__(self, index): + return weirdunicode(2*unicode.__getitem__(self, index)) + self.assertEqual( + filter(lambda x: x>=unicode("33"), weirdunicode("1234")), unicode("3344")) def test_float(self): From doerwalter@users.sourceforge.net Tue Feb 4 16:28:02 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue, 04 Feb 2003 08:28:02 -0800 Subject: [Python-checkins] python/dist/src/Python bltinmodule.c,2.272,2.273 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv5503/Python Modified Files: bltinmodule.c Log Message: filterstring() and filterunicode() in Python/bltinmodule.c blindly assumed that tp_as_sequence->sq_item always returns a str or unicode object. This might fail with str or unicode subclasses. This patch checks whether the object returned from __getitem__ is a str/unicode object and raises a TypeError if not (and the filter function returned true). Furthermore the result for __getitem__ can be more than one character long, so checks for enough memory have to be done. Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.272 retrieving revision 2.273 diff -C2 -d -r2.272 -r2.273 *** bltinmodule.c 3 Feb 2003 20:23:33 -0000 2.272 --- bltinmodule.c 4 Feb 2003 16:28:00 -0000 2.273 *************** *** 1893,1896 **** --- 1893,1897 ---- register int i, j; int len = PyString_Size(strobj); + int outlen = len; if (func == Py_None) { *************** *** 1922,1932 **** ok = PyObject_IsTrue(good); Py_DECREF(good); ! if (ok) ! PyString_AS_STRING((PyStringObject *)result)[j++] = ! PyString_AS_STRING((PyStringObject *)item)[0]; Py_DECREF(item); } ! if (j < len) _PyString_Resize(&result, j); --- 1923,1963 ---- ok = PyObject_IsTrue(good); Py_DECREF(good); ! if (ok) { ! int reslen; ! if (!PyString_Check(item)) { ! PyErr_SetString(PyExc_TypeError, "can't filter str to str:" ! " __getitem__ returned different type"); ! Py_DECREF(item); ! goto Fail_1; ! } ! reslen = PyString_GET_SIZE(item); ! if (reslen == 1) { ! PyString_AS_STRING(result)[j++] = ! PyString_AS_STRING(item)[0]; ! } else { ! /* do we need more space? */ ! int need = j + reslen + len-i-1; ! if (need > outlen) { ! /* overallocate, to avoid reallocations */ ! if (need<2*outlen) ! need = 2*outlen; ! if (_PyString_Resize(&result, need)) { ! Py_DECREF(item); ! return NULL; ! } ! outlen = need; ! } ! memcpy( ! PyString_AS_STRING(result) + j, ! PyString_AS_STRING(item), ! reslen ! ); ! j += reslen; ! } ! } Py_DECREF(item); } ! if (j < outlen) _PyString_Resize(&result, j); *************** *** 1947,1950 **** --- 1978,1982 ---- register int i, j; int len = PyUnicode_GetSize(strobj); + int outlen = len; if (func == Py_None) { *************** *** 1976,1986 **** ok = PyObject_IsTrue(good); Py_DECREF(good); ! if (ok) ! PyUnicode_AS_UNICODE((PyStringObject *)result)[j++] = ! PyUnicode_AS_UNICODE((PyStringObject *)item)[0]; Py_DECREF(item); } ! if (j < len) PyUnicode_Resize(&result, j); --- 2008,2048 ---- ok = PyObject_IsTrue(good); Py_DECREF(good); ! if (ok) { ! int reslen; ! if (!PyUnicode_Check(item)) { ! 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) { ! 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, to avoid reallocations */ ! if (need<2*outlen) ! need = 2*outlen; ! if (PyUnicode_Resize(&result, need)) { ! Py_DECREF(item); ! return NULL; ! } ! outlen = need; ! } ! memcpy( ! PyUnicode_AS_UNICODE(result) + j, ! PyUnicode_AS_UNICODE(item), ! reslen*sizeof(Py_UNICODE) ! ); ! j += reslen; ! } ! } Py_DECREF(item); } ! if (j < outlen) PyUnicode_Resize(&result, j); From neal@metaslash.com Tue Feb 4 16:51:10 2003 From: neal@metaslash.com (Neal Norwitz) Date: Tue, 04 Feb 2003 11:51:10 -0500 Subject: [Python-checkins] python/dist/src/Python bltinmodule.c,2.272,2.273 In-Reply-To: References: Message-ID: <20030204165110.GA24222@epoch.metaslash.com> > ! if (PyUnicode_Resize(&result, need)) { > ! Py_DECREF(item); > ! return NULL; > ! } Instead of returning NULL, should this goto Fail_1? It appears that _PyString_Resize() will free it's argument (result) on failure, but PyUnicode_Resize() doesn't. Neal From doerwalter@users.sourceforge.net Tue Feb 4 16:57:51 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue, 04 Feb 2003 08:57:51 -0800 Subject: [Python-checkins] python/dist/src/Python bltinmodule.c,2.273,2.274 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv24350/Python Modified Files: bltinmodule.c Log Message: PyUnicode_Resize() doesn't free its argument in case of a failure, so we can jump to the error handling code that does. (Spotted by Neal Norwitz) Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.273 retrieving revision 2.274 diff -C2 -d -r2.273 -r2.274 *** bltinmodule.c 4 Feb 2003 16:28:00 -0000 2.273 --- bltinmodule.c 4 Feb 2003 16:57:49 -0000 2.274 *************** *** 2029,2033 **** if (PyUnicode_Resize(&result, need)) { Py_DECREF(item); ! return NULL; } outlen = need; --- 2029,2033 ---- if (PyUnicode_Resize(&result, need)) { Py_DECREF(item); ! goto Fail_1; } outlen = need; From doerwalter@users.sourceforge.net Tue Feb 4 17:04:04 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue, 04 Feb 2003 09:04:04 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_builtin.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv27954/Lib/test Modified Files: test_builtin.py Log Message: Add a test that checks that filter() honors the sq_item slot for str and unicode subclasses not just for generating the output but for testing too. Index: test_builtin.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_builtin.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_builtin.py 4 Feb 2003 16:28:00 -0000 1.7 --- test_builtin.py 4 Feb 2003 17:04:01 -0000 1.8 *************** *** 378,381 **** --- 378,386 ---- self.assertEqual(filter(lambda x: x>="33", weirdstr("1234")), "3344") + class shiftstr(str): + def __getitem__(self, index): + return chr(ord(str.__getitem__(self, index))+1) + self.assertEqual(filter(lambda x: x>="3", shiftstr("1234")), "345") + if have_unicode: # test bltinmodule.c::filterunicode() *************** *** 395,398 **** --- 400,411 ---- self.assertEqual( filter(lambda x: x>=unicode("33"), weirdunicode("1234")), unicode("3344")) + + class shiftunicode(unicode): + def __getitem__(self, index): + return unichr(ord(unicode.__getitem__(self, index))+1) + self.assertEqual( + filter(lambda x: x>=unicode("3"), shiftunicode("1234")), + unicode("345") + ) def test_float(self): From tim_one@users.sourceforge.net Tue Feb 4 17:49:40 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 04 Feb 2003 09:49:40 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_copy_reg.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv20029/Lib/test Modified Files: test_copy_reg.py Log Message: Added basic tests of copy_reg's extension registry. Index: test_copy_reg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_copy_reg.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_copy_reg.py 26 Jan 2003 11:32:44 -0000 1.5 --- test_copy_reg.py 4 Feb 2003 17:49:36 -0000 1.6 *************** *** 8,11 **** --- 8,32 ---- + class ExtensionSaver: + # Remember current registration for code (if any), and remove it (if + # there is one). + def __init__(self, code): + self.code = code + if code in copy_reg._inverted_registry: + self.pair = copy_reg._inverted_registry[code] + copy_reg.remove_extension(self.pair[0], self.pair[1], code) + else: + self.pair = None + + # Restore previous registration for code. + def restore(self): + code = self.code + curpair = copy_reg._inverted_registry.get(code) + if curpair is not None: + copy_reg.remove_extension(curpair[0], curpair[1], code) + pair = self.pair + if pair is not None: + copy_reg.add_extension(pair[0], pair[1], code) + class CopyRegTestCase(unittest.TestCase): *************** *** 26,29 **** --- 47,107 ---- self.assertEquals(True, copy.copy(True)) + def test_extension_registry(self): + mod, func, code = 'junk1 ', ' junk2', 0xabcd + e = ExtensionSaver(code) + try: + # Shouldn't be in registry now. + self.assertRaises(ValueError, copy_reg.remove_extension, + mod, func, code) + copy_reg.add_extension(mod, func, code) + # Should be in the registry. + self.assert_(copy_reg._extension_registry[mod, func] == code) + self.assert_(copy_reg._inverted_registry[code] == (mod, func)) + # Shouldn't be in the cache. + self.assert_(code not in copy_reg._extension_cache) + # Redundant registration should be OK. + copy_reg.add_extension(mod, func, code) # shouldn't blow up + # Conflicting code. + self.assertRaises(ValueError, copy_reg.add_extension, + mod, func, code + 1) + self.assertRaises(ValueError, copy_reg.remove_extension, + mod, func, code + 1) + # Conflicting module name. + self.assertRaises(ValueError, copy_reg.add_extension, + mod[1:], func, code ) + self.assertRaises(ValueError, copy_reg.remove_extension, + mod[1:], func, code ) + # Conflicting function name. + self.assertRaises(ValueError, copy_reg.add_extension, + mod, func[1:], code) + self.assertRaises(ValueError, copy_reg.remove_extension, + mod, func[1:], code) + # Can't remove one that isn't registered at all. + if code + 1 not in copy_reg._inverted_registry: + self.assertRaises(ValueError, copy_reg.remove_extension, + mod[1:], func[1:], code + 1) + + finally: + e.restore() + + # Shouldn't be there anymore. + self.assert_((mod, func) not in copy_reg._extension_registry) + # The code *may* be in copy_reg._extension_registry, though, if + # we happened to pick on a registered code. So don't check for + # that. + + # Check valid codes at the limits. + for code in 1, 0x7fffffff: + e = ExtensionSaver(code) + try: + copy_reg.add_extension(mod, func, code) + copy_reg.remove_extension(mod, func, code) + finally: + e.restore() + + # Ensure invalid codes blow up. + for code in -1, 0, 0x80000000L: + self.assertRaises(ValueError, copy_reg.add_extension, + mod, func, code) def test_main(): From gvanrossum@users.sourceforge.net Tue Feb 4 17:53:59 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 04 Feb 2003 09:53:59 -0800 Subject: [Python-checkins] python/nondist/peps pep-0307.txt,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv22116 Modified Files: pep-0307.txt Log Message: Refactored according to 3 main cases. Index: pep-0307.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0307.txt,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** pep-0307.txt 4 Feb 2003 14:50:23 -0000 1.8 --- pep-0307.txt 4 Feb 2003 17:53:55 -0000 1.9 *************** *** 217,395 **** ! XXX Refactoring needed ! The following sections should really be reorganized according to ! the following cases: ! 1. classic classes, all protocols ! 2. new-style classes, protocols 0 and 1 ! 3. new-style classes, protocol 2 - The __newobj__ unpickling function ! When the unpickling function returned by __reduce__ (the first ! item of the returned tuple) has the name __newobj__, something ! special happens for pickle protocol 2. An unpickling function ! named __newobj__ is assumed to have the following semantics: ! def __newobj__(cls, *args): ! return cls.__new__(cls, *args) ! Pickle protocol 2 special-cases an unpickling function with this ! name, and emits a pickling opcode that, given 'cls' and 'args', ! will return cls.__new__(cls, *args) without also pickling a ! reference to __newobj__. This is the main reason why protocol 2 ! pickles are so much smaller than classic pickles. Of course, the ! pickling code cannot verify that a function named __newobj__ ! actually has the expected semantics. If you use an unpickling ! function named __newobj__ that returns something different, you ! deserve what you get. ! It is safe to use this feature under Python 2.2; there's nothing ! in the recommended implementation of __newobj__ that depends on ! Python 2.3. ! The __getstate__ and __setstate__ methods ! When there is no __reduce__ for an object, the primary ways to ! customize pickling is by specifying __getstate__ and/or ! __setstate__ methods. These are supported for classic classes as ! well as for new-style classes for which no __reduce__ exists. ! When __reduce__ exists, __getstate__ is not called (unless your ! __reduce__ implementation calls it), but __setstate__ will be ! called with the third item from the tuple returned by __reduce__, ! if not None. ! There's a subtle difference between classic and new-style classes ! here: if a classic class's __getstate__ returns None, ! self.__setstate__(None) will be called as part of unpickling. But ! if a new-style class's __getstate__ returns None, its __setstate__ ! won't be called at all as part of unpickling. ! The __getstate__ method is supposed to return a picklable version ! of an object's state that does not reference the object itself. ! If no __getstate__ method exists, a default state is assumed. ! There are several cases: ! - For a classic class, the default state is self.__dict__. ! - For a new-style class that has an instance __dict__ and no ! __slots__, the default state is self.__dict__. ! - For a new-style class that has no instance __dict__ and no ! __slots__, the default __state__ is None. ! - For a new-style class that has an instance __dict__ and ! __slots__, the default state is a tuple consisting of two ! dictionaries: the first being self.__dict__, and the second ! being a dictionary mapping slot names to slot values. Only ! slots that have a value are included in the latter. ! - For a new-style class that has __slots__ and no instance ! __dict__, the default state is a tuple whose first item is None ! and whose second item is a dictionary mapping slot names to slot ! values described in the previous bullet. ! The __setstate__ should take one argument; it will be called with ! the value returned by __getstate__ or with the default state ! described above if no __setstate__ method is defined. ! If no __setstate__ method exists, a default implementation is ! provided that can handle the state returned by the default ! __getstate__. - It is fine if a class implements one of these but not the other, - as long as it is compatible with the default version. ! New-style classes that inherit a default __reduce__ implementation ! from the ultimate base class 'object'. This implementation is not ! used for protocol 2, and then last four bullets above apply. For ! protocols 0 and 1, the default implementation looks for a ! __getstate__ method, and if none exists, it uses a simpler default ! strategy: ! - If there is an instance __dict__, the state is self.__dict__. ! - Otherwise, the state is None (and __setstate__ will not be ! called). Note that this strategy ignores slots. New-style classes that define slots and don't define __getstate__ in the same class that defines the slots automatically have a __getstate__ method added ! that raises TypeError. Protocol 2 ignores this __getstate__ ! method (recognized by the specific text of the error message). ! The __getinitargs__ and __getnewargs__ methods ! The __setstate__ method (or its default implementation) requires ! that a new object already exists so that its __setstate__ method ! can be called. The point is to create a new object that isn't ! fully initialized; in particular, the class's __init__ method ! should not be called if possible. ! The way this is done differs between classic and new-style ! classes. ! For classic classes, these are the possibilities: ! - Normally, the following trick is used: create an instance of a ! trivial classic class (one without any methods or instance ! variables) and then use __class__ assignment to change its class ! to the desired class. This creates an instance of the desired ! class with an empty __dict__ whose __init__ has not been called. ! - However, if the class has a method named __getinitargs__, the ! above trick is not used, and a class instance is created by ! using the tuple returned by __getinitargs__ as an argument list ! to the class constructor. This is done even if __getinitargs__ ! returns an empty tuple -- a __getinitargs__ method that returns ! () is not equivalent to not having __getinitargs__ at all. ! __getinitargs__ *must* return a tuple. ! - In restricted execution mode, the trick from the first bullet ! doesn't work; in this case, the class constructor is called with ! an empty argument list if no __getinitargs__ method exists. ! This means that in order for a classic class to be unpicklable ! in restricted mode, it must either implement __getinitargs__ or ! its constructor (i.e., its __init__ method) must be callable ! without arguments. ! For new-style classes, these are the possibilities: ! - When using protocol 0 or 1, a default __reduce__ implementation ! is normally inherited from the ultimate base class class ! 'object'. This implementation finds the nearest base class that ! is implemented in C (either as a built-in type or as a type ! defined by an extension class). Calling this base class B and ! the class of the object to be pickled C, the new object is ! created at unpickling time using the following code: ! obj = B.__new__(C, state) ! B.__init__(obj, state) ! where state is a value computed at pickling time as follows: ! state = B(obj) ! This only works when B is not C, and only for certain classes ! B. It does work for the following built-in classes: int, long, ! float, complex, str, unicode, tuple, list, dict; and this is its ! main redeeming factor. ! - When using protocol 2, the default __reduce__ implementation ! inherited from 'object' is ignored. Instead, a new pickling ! opcode is generated that causes a new object to be created as ! follows: obj = C.__new__(C, *args) where args is either the empty tuple, or the tuple returned by ! the __getnewargs__ method, if defined. --- 217,490 ---- ! Customizing pickling absent a __reduce__ implementation ! If no __reduce__ implementation is available for a particular ! class, there are three cases that need to be considered ! separately, because they are handled differently: ! 1. classic class instances, all protocols ! 2. new-style class instances, protocols 0 and 1 ! 3. new-style class instances, protocol 2 + Types implemented in C are considered new-style classes. However, + except for the common built-in types, these need to provide a + __reduce__ implementation in order to be picklable with protocols + 0 or 1. Protocol 2 supports built-in types providing + __getnewargs__, __getstate__ and __setstate__ as well. ! Case 1: pickling classic class instances ! This case is the same for all protocols, and is unchanged from ! Python 2.1. ! For classic classes, __reduce__ is not used. Instead, classic ! classes can customize their pickling by providing methods named ! __getstate__, __setstate__ and __getinitargs__. Absent these, a ! default pickling strategy for classic class instances is ! implemented that works as long as all instance variables are ! picklable. This default strategy is documented in terms of ! default implementations of __getstate__ and __setstate__. ! The primary ways to customize pickling of classic class instances ! is by specifying __getstate__ and/or __setstate__ methods. It is ! fine if a class implements one of these but not the other, as long ! as it is compatible with the default version. + The __getstate__ method ! The __getstate__ method should return a picklable value ! representing the object's state without referencing the object ! itself. If no __getstate__ method exists, a default ! implementation is used that returns self.__dict__. ! The __setstate__ method ! The __setstate__ method should take one argument; it will be ! called with the value returned by __getstate__ (or its default ! implementation). ! If no __setstate__ method exists, a default implementation is ! provided that assumes the state is a dictionary mapping instance ! variable names to values. The default implementation tries two ! things: ! - First, it tries to call self.__dict__.update(state). ! - If the update() call fails with a RuntimeError exception, it ! calls setattr(self, key, value) for each (key, value) pair in ! the state dictionary. This only happens when unpickling in ! restricted execution mode (see the rexec standard library ! module). ! The __getinitargs__ method ! The __setstate__ method (or its default implementation) requires ! that a new object already exists so that its __setstate__ method ! can be called. The point is to create a new object that isn't ! fully initialized; in particular, the class's __init__ method ! should not be called if possible. ! These are the possibilities: ! - Normally, the following trick is used: create an instance of a ! trivial classic class (one without any methods or instance ! variables) and then use __class__ assignment to change its ! class to the desired class. This creates an instance of the ! desired class with an empty __dict__ whose __init__ has not ! been called. ! - However, if the class has a method named __getinitargs__, the ! above trick is not used, and a class instance is created by ! using the tuple returned by __getinitargs__ as an argument ! list to the class constructor. This is done even if ! __getinitargs__ returns an empty tuple -- a __getinitargs__ ! method that returns () is not equivalent to not having ! __getinitargs__ at all. __getinitargs__ *must* return a ! tuple. ! - In restricted execution mode, the trick from the first bullet ! doesn't work; in this case, the class constructor is called ! with an empty argument list if no __getinitargs__ method ! exists. This means that in order for a classic class to be ! unpicklable in restricted execution mode, it must either ! implement __getinitargs__ or its constructor (i.e., its ! __init__ method) must be callable without arguments. ! Case 2: pickling new-style class instances using protocols 0 or 1 ! This case is unchanged from Python 2.2. For better pickling of ! new-style class instances when backwards compatibility is not an ! issue, protocol 2 should be used; see case 3 below. ! New-style classes, whether implemented in C or in Python, inherit ! a default __reduce__ implementation from the universal base class ! 'object'. ! ! This default __reduce__ implementation is not used for those ! built-in types for which the pickle module has built-in support. ! Here's a full list of those types: ! ! - Concrete built-in types: NoneType, bool, int, float, complex, ! str, unicode, tuple, list, dict. (Complex is supported by ! virtue of a __reduce__ implementation registered in copy_reg.) ! In Jython, PyStringMap is also included in this list. ! ! - Classic instances. ! ! - Classic class objects, Python function objects, built-in ! function and method objects, and new-style type objects (== ! new-style class objects). These are pickled by name, not by ! value: at unpickling time, a reference to an object with the ! same name (the fully qualified module name plus the variable ! name in that module) is substituted. ! ! The default __reduce__ implementation will fail at pickling time ! for built-in types not mentioned above. ! ! For new-style classes implemented in Python, the default ! __reduce__ implementation works as follows: ! ! Let D be the class on the object to be pickled. First, find the ! nearest base class that is implemented in C (either as a ! built-in type or as a type defined by an extension class). Call ! this base class B, and the class of the object to be pickled D. ! Unless B is the class 'object', instances of class B must be ! picklable, either by having built-in support (as defined in the ! above three bullet points), or by having a non-default ! __reduce__ implementation. B must not be the same class as D ! (if it were, it would mean that D is not implemented in Python). ! ! The new object is created at unpickling time using the following ! code: ! ! obj = B.__new__(D, state) ! B.__init__(obj, state) ! ! where state is a value computed at pickling time as follows: ! ! state = B(obj) ! ! Objects for which this default __reduce__ implementation is used ! can customize it by defining __getstate__ and/or __setstate__ ! methods. These work almost the same as described for classic ! classes above, except that if __getstate__ returns an object (of ! any type) whose value is considered false (e.g. None, or a number ! that is zero, or an empty sequence or mapping), this state is not ! pickled and __setstate__ will not be called at all. Note that this strategy ignores slots. New-style classes that define slots and don't define __getstate__ in the same class that defines the slots automatically have a __getstate__ method added ! that raises TypeError. ! Case 3: pickling new-style class instances using protocol 2 ! Under protocol 2, the default __reduce__ implementation inherited ! from the 'object' base class is *ignored*. Instead, a different ! default implementation is used, which allows more efficient ! pickling of new-style class instances than possible with protocols ! 0 or 1, at the cost of backward incompatibility with Python 2.2. ! The customization uses three special methods: __getstate__, ! __setstate__ and __getnewargs__. It is fine if a class implements ! one or more but not all of these, as long as it is compatible with ! the default implementations. ! The __getstate__ method ! The __getstate__ method should return a picklable value ! representing the object's state without referencing the object ! itself. If no __getstate__ method exists, a default ! implementation is used which is described below. ! There's a subtle difference between classic and new-style ! classes here: if a classic class's __getstate__ returns None, ! self.__setstate__(None) will be called as part of unpickling. ! But if a new-style class's __getstate__ returns None, its ! __setstate__ won't be called at all as part of unpickling. ! If no __getstate__ method exists, a default state is assumed. ! There are several cases: ! - For a new-style class that has an instance __dict__ and no ! __slots__, the default state is self.__dict__. ! - For a new-style class that has no instance __dict__ and no ! __slots__, the default __state__ is None. ! - For a new-style class that has an instance __dict__ and ! __slots__, the default state is a tuple consisting of two ! dictionaries: the first being self.__dict__, and the second ! being a dictionary mapping slot names to slot values. Only ! slots that have a value are included in the latter. ! - For a new-style class that has __slots__ and no instance ! __dict__, the default state is a tuple whose first item is ! None and whose second item is a dictionary mapping slot names ! to slot values described in the previous bullet. ! Note that new-style classes that define slots and don't define ! __getstate__ in the same class that defines the slots ! automatically have a __getstate__ method added that raises ! TypeError. Protocol 2 ignores this __getstate__ method ! (recognized by the specific text of the error message). ! The __setstate__ method ! The __setstate__ should take one argument; it will be called ! with the value returned by __getstate__ or with the default ! state described above if no __setstate__ method is defined. ! ! If no __setstate__ method exists, a default implementation is ! provided that can handle the state returned by the default ! __getstate__, described above. ! ! The __getnewargs__ method ! ! Like for classic classes, the __setstate__ method (or its ! default implementation) requires that a new object already ! exists so that its __setstate__ method can be called. ! ! In protocol 2, a new pickling opcode is used that causes a new ! object to be created as follows: obj = C.__new__(C, *args) where args is either the empty tuple, or the tuple returned by ! the __getnewargs__ method, if defined. __getnewargs__ must ! return a tuple. The absence of a __getnewargs__ method is ! equivalent to the existence of one that returns (). ! ! ! The __newobj__ unpickling function ! ! When the unpickling function returned by __reduce__ (the first ! item of the returned tuple) has the name __newobj__, something ! special happens for pickle protocol 2. An unpickling function ! named __newobj__ is assumed to have the following semantics: ! ! def __newobj__(cls, *args): ! return cls.__new__(cls, *args) ! ! Pickle protocol 2 special-cases an unpickling function with this ! name, and emits a pickling opcode that, given 'cls' and 'args', ! will return cls.__new__(cls, *args) without also pickling a ! reference to __newobj__ (this is the same pickling opcode used by ! protocol 2 for a new-style class instance when no __reduce__ ! implementation exists). This is the main reason why protocol 2 ! pickles are much smaller than classic pickles. Of course, the ! pickling code cannot verify that a function named __newobj__ ! actually has the expected semantics. If you use an unpickling ! function named __newobj__ that returns something different, you ! deserve what you get. ! ! It is safe to use this feature under Python 2.2; there's nothing ! in the recommended implementation of __newobj__ that depends on ! Python 2.3. From doerwalter@users.sourceforge.net Tue Feb 4 18:02:31 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue, 04 Feb 2003 10:02:31 -0800 Subject: [Python-checkins] python/dist/src/Modules _iconv_codec.c,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv25990/Modules Modified Files: _iconv_codec.c Log Message: Use size_t instead of int for various variables to prevent signed/unsigned comparison warnings on the call to iconv(). Fix comment typos. >From SF patch #680146. Index: _iconv_codec.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_iconv_codec.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** _iconv_codec.c 31 Jan 2003 17:19:07 -0000 1.7 --- _iconv_codec.c 4 Feb 2003 18:02:28 -0000 1.8 *************** *** 43,47 **** staticforward PyTypeObject iconvcodec_Type; ! /* does the choosen internal encoding require * byteswapping to get native endianness? * 0=no, 1=yes, -1=unknown */ --- 43,47 ---- staticforward PyTypeObject iconvcodec_Type; ! /* does the chosen internal encoding require * byteswapping to get native endianness? * 0=no, 1=yes, -1=unknown */ *************** *** 147,151 **** while (inplen > 0) { ! if (iconv(self->enchdl, (char**)&inp, &inplen, &out, &outlen) == -1) { char reason[128]; int errpos; --- 147,151 ---- while (inplen > 0) { ! if (iconv(self->enchdl, (char**)&inp, &inplen, &out, &outlen) == (size_t)-1) { char reason[128]; int errpos; *************** *** 354,358 **** while (inplen > 0) { char *oldout = out; ! char res = iconv(self->dechdl, (char**)&inp, &inplen, &out, &outlen); if (byteswap) { --- 354,358 ---- while (inplen > 0) { char *oldout = out; ! size_t res = iconv(self->dechdl, (char**)&inp, &inplen, &out, &outlen); if (byteswap) { *************** *** 373,377 **** } } ! if (res == -1) { char reason[128], *reasonpos = (char *)reason; int errpos; --- 373,377 ---- } } ! if (res == (size_t)-1) { char reason[128], *reasonpos = (char *)reason; int errpos; *************** *** 663,671 **** char in = 1; char *inptr = ∈ ! int insize = 1; Py_UNICODE out = 0; char *outptr = (char *)&out; ! int outsize = sizeof(out); ! int res; iconv_t hdl = iconv_open(UNICODE_ENCODING, "ASCII"); --- 663,671 ---- char in = 1; char *inptr = ∈ ! size_t insize = 1; Py_UNICODE out = 0; char *outptr = (char *)&out; ! size_t outsize = sizeof(out); ! size_t res; iconv_t hdl = iconv_open(UNICODE_ENCODING, "ASCII"); *************** *** 675,682 **** res = iconv(hdl, &inptr, &insize, &outptr, &outsize); ! if (res == -1) Py_FatalError("can't initialize the _iconv_codec module: iconv() failed"); ! /* Check whether conv() returned native endianess or not for the choosen encoding */ if (out == 0x1) byteswap = 0; --- 675,682 ---- res = iconv(hdl, &inptr, &insize, &outptr, &outsize); ! if (res == (size_t)-1) Py_FatalError("can't initialize the _iconv_codec module: iconv() failed"); ! /* Check whether conv() returned native endianess or not for the chosen encoding */ if (out == 0x1) byteswap = 0; From gvanrossum@users.sourceforge.net Tue Feb 4 19:12:28 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 04 Feb 2003 11:12:28 -0800 Subject: [Python-checkins] python/nondist/peps pep-0307.txt,1.9,1.10 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv26330 Modified Files: pep-0307.txt Log Message: Introduce extension codes. Index: pep-0307.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0307.txt,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** pep-0307.txt 4 Feb 2003 17:53:55 -0000 1.9 --- pep-0307.txt 4 Feb 2003 19:12:25 -0000 1.10 *************** *** 489,492 **** --- 489,568 ---- + The extension registry + + Protocol 2 supports a new mechanism to reduce the size of pickles. + + When class instances (classic or new-style) are pickled, the full + name of the class (module name including package name, and class + name) is included in the pickle. Especially for applications that + generate many small pickles, this is a lot of overhead that has to + be repeated in each pickle. For large pickles, when using + protocol 1, repeated references to the same class name are + compressed using the "memo" feature; but each class name must be + spelled in full at least once per pickle, and this causes a lot of + overhead for small pickles. + + The extension registry allows one to represent the most frequently + used names by small integers, which are pickled very efficiently: + an extension code in the range 1-255 requires only two bytes + including the opcode, one in the range 256-65535 requires only + three bytes including the opcode. + + One of the design goals of the pickle protocol is to make pickles + "context-free": as long as you have installed the modules + containing the classes referenced by a pickle, you can unpickle + it, without needing to import any of those classes ahead of time. + + Unbridled use of extension codes could jeopardize this desirable + property of pickles. Therefore, the main use of extension codes + is reserved for a set of codes to be standardized by some + standard-setting body. This being Python, the standard-setting + body is the PSF. From time to time, the PSF will decide on a + table mapping extension codes to class names (or occasionally + names of other global objects; functions are also eligible). This + table will be incorporated in the next Python release(s). + + However, for some applications, like Zope, context-free pickles + are not a requirement, and waiting for the PSF to standardize + some codes may not be practical. Two solutions are offered for + such applications. + + First of all, a few ranges of extension codes is reserved for + private use. Any application can register codes in these ranges. + Two applications exchanging pickles using codes in these ranges + need to have some out-of-band mechanism to agree on the mapping + between extension codes and names. + + Second, some large Python projects (e.g. Zope or Twisted) can be + assigned a range of extension codes outside the "private use" + range that they can assign as they see fit. + + The extension registry is defined as a mapping between extension + codes and names. When an extension code is unpickled, it ends up + producing an object, but this object is gotten by interpreting the + name as a module name followed by a class (or function) name. The + mapping from names to objects is cached. It is quite possible + that certain names cannot be imported; that should not be a + problem as long as no pickle containing a reference to such names + has to be unpickled. (The same issue already exists for direct + references to such names in pickles that use protocols 0 or 1.) + + Here is the proposed initial assigment of extension code ranges: + + First Last Count Purpose + + 0 0 1 Reserved -- will never be used + 1 127 127 Reserved for Python standard library + 128 191 64 Reserved for Zope 3 + 192 239 48 Reserved for 3rd parties + 240 255 16 Reserved for private use (will never be assigned) + 256 Max Max Reserved for future assignment + + 'Max' stands for 2147483647, or 2**31-1. This is a hard + limitation of the protocol as currently defined. + + At the moment, no specific extension codes have been assigned yet. + + TBD From fdrake@users.sourceforge.net Tue Feb 4 19:13:09 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Tue, 04 Feb 2003 11:13:09 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libposixpath.tex,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv26414 Modified Files: libposixpath.tex Log Message: supports_unicode_filenames was not in the right location. Index: libposixpath.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libposixpath.tex,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** libposixpath.tex 31 Dec 2002 13:38:28 -0000 1.32 --- libposixpath.tex 4 Feb 2003 19:13:07 -0000 1.33 *************** *** 230,240 **** assignment.) - \begin{datadesc}{supports_unicode_filenames} - True if arbitrary Unicode strings can be used as file names (within - limitations imposed by the file system), and if os.listdir returns - Unicode strings for a Unicode argument. - \versionadded{2.3} - \end{datadesc} - \begin{notice} Symbolic links to directories are not treated as subdirectories, and --- 230,233 ---- *************** *** 246,247 **** --- 239,248 ---- \end{notice} \end{funcdesc} + + \begin{datadesc}{supports_unicode_filenames} + True if arbitrary Unicode strings can be used as file names (within + limitations imposed by the file system), and if + \function{os.listdir()} returns Unicode strings for a Unicode + argument. + \versionadded{2.3} + \end{datadesc} From gvanrossum@users.sourceforge.net Tue Feb 4 19:28:19 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 04 Feb 2003 11:28:19 -0800 Subject: [Python-checkins] python/nondist/peps pep-0307.txt,1.10,1.11 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv639 Modified Files: pep-0307.txt Log Message: Document the extension registry API. Remove mention of Twisted (they don't want it). Index: pep-0307.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0307.txt,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** pep-0307.txt 4 Feb 2003 19:12:25 -0000 1.10 --- pep-0307.txt 4 Feb 2003 19:28:16 -0000 1.11 *************** *** 534,540 **** between extension codes and names. ! Second, some large Python projects (e.g. Zope or Twisted) can be ! assigned a range of extension codes outside the "private use" ! range that they can assign as they see fit. The extension registry is defined as a mapping between extension --- 534,540 ---- between extension codes and names. ! Second, some large Python projects (e.g. Zope) can be assigned a ! range of extension codes outside the "private use" range that they ! can assign as they see fit. The extension registry is defined as a mapping between extension *************** *** 557,566 **** 192 239 48 Reserved for 3rd parties 240 255 16 Reserved for private use (will never be assigned) ! 256 Max Max Reserved for future assignment ! 'Max' stands for 2147483647, or 2**31-1. This is a hard ! limitation of the protocol as currently defined. At the moment, no specific extension codes have been assigned yet. --- 557,597 ---- 192 239 48 Reserved for 3rd parties 240 255 16 Reserved for private use (will never be assigned) ! 256 MAX MAX Reserved for future assignment ! MAX stands for 2147483647, or 2**31-1. This is a hard limitation ! of the protocol as currently defined. At the moment, no specific extension codes have been assigned yet. + + + Extension registry API + + The extension registry is maintained as private global variables + in the copy_reg module. The following three functions are defined + in this module to manipulate the registry: + + add_extension(module, name, code) + Register an extension code. The module and name arguments + must be strings; code must be an int in the inclusive range 1 + through MAX. This must either register a new (module, name) + pair to a new code, or be a redundant repeat of a previous + call that was not canceled by a remove_extension() call; a + (module, name) pair may not be mapped to more than one code, + nor may a code be mapped to more than one (module, name) + pair. (XXX Aliasing may actually cause as problem for this + requirement; we'll see as we go.) + + remove_extension(module, name, code) + Arguments are as for add_extension(). Remove a previously + registered mapping between (module, name) and code. + + clear_extension_cache() + The implementation of extension codes may use a cache to speed + up loading objects that are named frequently. This cache can + be emptied (removing references to cached objects) by calling + this method. + + Note that the API does not enforce the standard range assignments. + It is up to applications to respect these. From lemburg@users.sourceforge.net Tue Feb 4 19:35:08 2003 From: lemburg@users.sourceforge.net (lemburg@users.sourceforge.net) Date: Tue, 04 Feb 2003 11:35:08 -0800 Subject: [Python-checkins] python/dist/src/Modules _codecsmodule.c,2.16,2.17 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv2848/Modules Modified Files: _codecsmodule.c Log Message: Fix for [ 543344 ] Interpreter crashes when recoding; suggested by Michael Stone (mbrierst). Python 2.1.4, 2.2.2 candidate. Index: _codecsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_codecsmodule.c,v retrieving revision 2.16 retrieving revision 2.17 diff -C2 -d -r2.16 -r2.17 *** _codecsmodule.c 31 Oct 2002 13:36:29 -0000 2.16 --- _codecsmodule.c 4 Feb 2003 19:35:03 -0000 2.17 *************** *** 168,173 **** return NULL; ! if (PyUnicode_Check(obj)) return codec_tuple(obj, PyUnicode_GET_SIZE(obj)); else { if (PyObject_AsReadBuffer(obj, (const void **)&data, &size)) --- 168,175 ---- return NULL; ! if (PyUnicode_Check(obj)) { ! Py_INCREF(obj); return codec_tuple(obj, PyUnicode_GET_SIZE(obj)); + } else { if (PyObject_AsReadBuffer(obj, (const void **)&data, &size)) From doerwalter@users.sourceforge.net Tue Feb 4 20:24:48 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue, 04 Feb 2003 12:24:48 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_builtin.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv25412/Lib/test Modified Files: test_builtin.py Log Message: Make sure filter() never returns tuple, str or unicode subclasses. (Discussed in SF patch #665835) Index: test_builtin.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_builtin.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** test_builtin.py 4 Feb 2003 17:04:01 -0000 1.8 --- test_builtin.py 4 Feb 2003 20:24:45 -0000 1.9 *************** *** 409,412 **** --- 409,435 ---- ) + def test_filter_subclasses(self): + # test, that filter() never returns tuple, str or unicode subclasses + funcs = (None, lambda x: True) + class tuple2(tuple): + pass + class str2(str): + pass + inputs = { + tuple2: [(), (1,2,3)], + str2: ["", "123"] + } + if have_unicode: + class unicode2(unicode): + pass + inputs[unicode2] = [unicode(), unicode("123")] + + for func in funcs: + for (cls, inps) in inputs.iteritems(): + for inp in inps: + out = filter(func, cls(inp)) + self.assertEqual(inp, out) + self.assert_(not isinstance(out, cls)) + def test_float(self): self.assertEqual(float(3.14), 3.14) From doerwalter@users.sourceforge.net Tue Feb 4 20:24:48 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue, 04 Feb 2003 12:24:48 -0800 Subject: [Python-checkins] python/dist/src/Python bltinmodule.c,2.274,2.275 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv25412/Python Modified Files: bltinmodule.c Log Message: Make sure filter() never returns tuple, str or unicode subclasses. (Discussed in SF patch #665835) Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.274 retrieving revision 2.275 diff -C2 -d -r2.274 -r2.275 *** bltinmodule.c 4 Feb 2003 16:57:49 -0000 2.274 --- bltinmodule.c 4 Feb 2003 20:24:43 -0000 2.275 *************** *** 1839,1843 **** if (len == 0) { ! Py_INCREF(tuple); return tuple; } --- 1839,1846 ---- if (len == 0) { ! if (PyTuple_CheckExact(tuple)) ! Py_INCREF(tuple); ! else ! tuple = PyTuple_New(0); return tuple; } *************** *** 1896,1901 **** if (func == Py_None) { ! /* No character is ever false -- share input string */ ! Py_INCREF(strobj); return strobj; } --- 1899,1911 ---- if (func == Py_None) { ! /* No character is ever false -- share input string ! * (if it's not a subclass) */ ! if (PyString_CheckExact(strobj)) ! Py_INCREF(strobj); ! else ! strobj = PyString_FromStringAndSize( ! PyString_AS_STRING(strobj), ! len ! ); return strobj; } *************** *** 1981,1986 **** if (func == Py_None) { ! /* No character is ever false -- share input string */ ! Py_INCREF(strobj); return strobj; } --- 1991,2003 ---- if (func == Py_None) { ! /* No character is ever false -- share input string ! * (it if's not a subclass) */ ! if (PyUnicode_CheckExact(strobj)) ! Py_INCREF(strobj); ! else ! strobj = PyUnicode_FromUnicode( ! PyUnicode_AS_UNICODE(strobj), ! len ! ); return strobj; } From lemburg@users.sourceforge.net Tue Feb 4 19:35:36 2003 From: lemburg@users.sourceforge.net (lemburg@users.sourceforge.net) Date: Tue, 04 Feb 2003 11:35:36 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_codecs.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv2848/Lib/test Modified Files: test_codecs.py Log Message: Fix for [ 543344 ] Interpreter crashes when recoding; suggested by Michael Stone (mbrierst). Python 2.1.4, 2.2.2 candidate. Index: test_codecs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_codecs.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_codecs.py 3 Sep 2002 13:53:40 -0000 1.4 --- test_codecs.py 4 Feb 2003 19:35:01 -0000 1.5 *************** *** 28,31 **** --- 28,39 ---- self.assertEquals(codecs.escape_decode(""), ("", 0)) + class RecodingTest(unittest.TestCase): + def test_recoding(self): + f = StringIO.StringIO() + f2 = codecs.EncodedFile(f, "unicode_internal", "utf-8") + f2.write(u"a") + f2.close() + # Python used to crash on this at exit because of a refcount + # bug in _codecsmodule.c def test_main(): *************** *** 33,36 **** --- 41,45 ---- suite.addTest(unittest.makeSuite(UTF16Test)) suite.addTest(unittest.makeSuite(EscapeDecodeTest)) + suite.addTest(unittest.makeSuite(RecodingTest)) test_support.run_suite(suite) From nnorwitz@users.sourceforge.net Tue Feb 4 20:45:23 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 04 Feb 2003 12:45:23 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.56,1.57 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv2882/Modules Modified Files: datetimemodule.c Log Message: Whitespace normalization Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.56 retrieving revision 1.57 diff -C2 -d -r1.56 -r1.57 *** datetimemodule.c 1 Feb 2003 04:40:04 -0000 1.56 --- datetimemodule.c 4 Feb 2003 20:45:17 -0000 1.57 *************** *** 2871,2875 **** PyDoc_STR("Abstract base class for time zone info objects."); ! statichere PyTypeObject PyDateTime_TZInfoType = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ --- 2871,2875 ---- PyDoc_STR("Abstract base class for time zone info objects."); ! statichere PyTypeObject PyDateTime_TZInfoType = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ From nnorwitz@users.sourceforge.net Tue Feb 4 20:46:53 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 04 Feb 2003 12:46:53 -0800 Subject: [Python-checkins] python/dist/src/Modules _iconv_codec.c,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv3804/Modules Modified Files: _iconv_codec.c Log Message: Remove forward static reference since it is not required Index: _iconv_codec.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_iconv_codec.c,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** _iconv_codec.c 4 Feb 2003 18:02:28 -0000 1.8 --- _iconv_codec.c 4 Feb 2003 20:46:50 -0000 1.9 *************** *** 41,46 **** PyDoc_STRVAR(iconvcodec_doc, "iconvcodec object"); - staticforward PyTypeObject iconvcodec_Type; - /* does the chosen internal encoding require * byteswapping to get native endianness? --- 41,44 ---- *************** *** 609,613 **** } ! statichere PyTypeObject iconvcodec_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, /* Number of items for varobject */ --- 607,611 ---- } ! static PyTypeObject iconvcodec_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, /* Number of items for varobject */ From nascheme@users.sourceforge.net Tue Feb 4 20:55:46 2003 From: nascheme@users.sourceforge.net (nascheme@users.sourceforge.net) Date: Tue, 04 Feb 2003 12:55:46 -0800 Subject: [Python-checkins] python/dist/src/Python getargs.c,2.95,2.96 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv8360/Python Modified Files: getargs.c Log Message: If a float is passed where a int is expected, issue a DeprecationWarning instead of raising a TypeError. Closes #660144 (again). Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.95 retrieving revision 2.96 diff -C2 -d -r2.95 -r2.96 *** getargs.c 24 Jan 2003 22:15:21 -0000 2.95 --- getargs.c 4 Feb 2003 20:55:40 -0000 2.96 *************** *** 388,391 **** --- 388,404 ---- #define CONV_UNICODE "(unicode conversion error)" + /* explicitly check for float arguments when integers are expected. For now + * signal a warning. Returns true if an exception was raised. */ + static int + float_argument_error(PyObject *arg) + { + if (PyFloat_Check(arg) && + PyErr_Warn(PyExc_DeprecationWarning, + "integer argument expected, got float" )) + return 1; + else + return 0; + } + /* Convert a non-tuple argument. Return NULL if conversion went OK, or a string with a message describing the failure. The message is *************** *** 410,415 **** char *p = va_arg(*p_va, char *); long ival; ! if (PyFloat_Check(arg)) ! return converterr("integer", arg, msgbuf, bufsize); ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) --- 423,428 ---- char *p = va_arg(*p_va, char *); long ival; ! if (float_argument_error(arg)) ! return NULL; ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) *************** *** 434,439 **** char *p = va_arg(*p_va, char *); long ival; ! if (PyFloat_Check(arg)) ! return converterr("integer", arg, msgbuf, bufsize); ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) --- 447,452 ---- char *p = va_arg(*p_va, char *); long ival; ! if (float_argument_error(arg)) ! return NULL; ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) *************** *** 457,462 **** short *p = va_arg(*p_va, short *); long ival; ! if (PyFloat_Check(arg)) ! return converterr("integer", arg, msgbuf, bufsize); ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) --- 470,475 ---- short *p = va_arg(*p_va, short *); long ival; ! if (float_argument_error(arg)) ! return NULL; ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) *************** *** 481,486 **** unsigned short *p = va_arg(*p_va, unsigned short *); long ival; ! if (PyFloat_Check(arg)) ! return converterr("integer", arg, msgbuf, bufsize); ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) --- 494,499 ---- unsigned short *p = va_arg(*p_va, unsigned short *); long ival; ! if (float_argument_error(arg)) ! return NULL; ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) *************** *** 504,509 **** int *p = va_arg(*p_va, int *); long ival; ! if (PyFloat_Check(arg)) ! return converterr("integer", arg, msgbuf, bufsize); ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) --- 517,522 ---- int *p = va_arg(*p_va, int *); long ival; ! if (float_argument_error(arg)) ! return NULL; ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) *************** *** 527,532 **** long *p = va_arg(*p_va, long *); long ival; ! if (PyFloat_Check(arg)) ! return converterr("integer", arg, msgbuf, bufsize); ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) --- 540,545 ---- long *p = va_arg(*p_va, long *); long ival; ! if (float_argument_error(arg)) ! return NULL; ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) From tim_one@users.sourceforge.net Tue Feb 4 20:56:46 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 04 Feb 2003 12:56:46 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.42,1.43 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv7825/Lib/test Modified Files: pickletester.py Log Message: cPickle now generates proto 2 EXT[124] when appropriate. Moved such EXT tests as currently exist from TempAbstractPickleTests to AbstractPickleTests, so that test_cpickle runs them too. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** pickletester.py 3 Feb 2003 22:32:18 -0000 1.42 --- pickletester.py 4 Feb 2003 20:56:08 -0000 1.43 *************** *** 584,604 **** self.assertEqual(x.__dict__, y.__dict__, detail) - # XXX Temporary hack, so long as the C implementation of pickle protocol - # XXX 2 isn't ready. When it is, move the methods in TempAbstractPickleTests - # XXX into AbstractPickleTests above, and get rid of TempAbstractPickleTests - # XXX along with the references to it in test_pickle.py. - class TempAbstractPickleTests(unittest.TestCase): - - def test_newobj_list_slots(self): - x = SlotList([1, 2, 3]) - x.foo = 42 - x.bar = "hello" - s = self.dumps(x, 2) - y = self.loads(s) - self.assertEqual(list(x), list(y)) - self.assertEqual(x.__dict__, y.__dict__) - self.assertEqual(x.foo, y.foo) - self.assertEqual(x.bar, y.bar) - # Register a type with copy_reg, with extension code extcode. Pickle # an object of that type. Check that the resulting pickle uses opcode --- 584,587 ---- *************** *** 639,643 **** def test_global_ext4(self): ! self.produce_global_ext(0xffffff0, pickle.EXT4) --- 622,643 ---- def test_global_ext4(self): ! self.produce_global_ext(0xabcdef0, pickle.EXT4) ! ! # XXX Temporary hack, so long as the C implementation of pickle protocol ! # XXX 2 isn't ready. When it is, move the methods in TempAbstractPickleTests ! # XXX into AbstractPickleTests above, and get rid of TempAbstractPickleTests ! # XXX along with the references to it in test_pickle.py. ! class TempAbstractPickleTests(unittest.TestCase): ! ! def test_newobj_list_slots(self): ! x = SlotList([1, 2, 3]) ! x.foo = 42 ! x.bar = "hello" ! s = self.dumps(x, 2) ! y = self.loads(s) ! self.assertEqual(list(x), list(y)) ! self.assertEqual(x.__dict__, y.__dict__) ! self.assertEqual(x.foo, y.foo) ! self.assertEqual(x.bar, y.bar) From nascheme@users.sourceforge.net Tue Feb 4 20:59:49 2003 From: nascheme@users.sourceforge.net (nascheme@users.sourceforge.net) Date: Tue, 04 Feb 2003 12:59:49 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.640,1.641 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv10115/Misc Modified Files: NEWS Log Message: If a float is passed where a int is expected, issue a DeprecationWarning instead of raising a TypeError. Closes #660144 (again). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.640 retrieving revision 1.641 diff -C2 -d -r1.640 -r1.641 *** NEWS 3 Feb 2003 20:53:14 -0000 1.640 --- NEWS 4 Feb 2003 20:59:40 -0000 1.641 *************** *** 224,230 **** ----- ! - The PyArg_Parse functions now raise a TypeError instead of truncating float ! arguments if an integer is specified (this affects the 'b', 'B', 'h', 'H', ! 'i', and 'l' codes). --- 224,231 ---- ----- ! - The PyArg_Parse functions now issue a DeprecationWarning if a float ! argument is provided when an integer is specified (this affects the 'b', ! 'B', 'h', 'H', 'i', and 'l' codes). Future versions of Python will ! raise a TypeError. From tim_one@users.sourceforge.net Tue Feb 4 20:56:50 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 04 Feb 2003 12:56:50 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.123,2.124 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv7825/Modules Modified Files: cPickle.c Log Message: cPickle now generates proto 2 EXT[124] when appropriate. Moved such EXT tests as currently exist from TempAbstractPickleTests to AbstractPickleTests, so that test_cpickle runs them too. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.123 retrieving revision 2.124 diff -C2 -d -r2.123 -r2.124 *** cPickle.c 4 Feb 2003 05:20:32 -0000 2.123 --- cPickle.c 4 Feb 2003 20:56:09 -0000 2.124 *************** *** 110,113 **** --- 110,116 ---- static PyObject *extension_cache; + /* For looking up name pairs in copy_reg._extension_registry. */ + static PyObject *two_tuple; + static PyObject *__class___str, *__getinitargs___str, *__dict___str, *__getstate___str, *__setstate___str, *__name___str, *__reduce___str, *************** *** 1932,1936 **** Py_DECREF(klass); cPickle_ErrFormat(PicklingError, ! "Can't pickle %s: it's not the same object as %s.%s", "OSS", args, module, global_name); goto finally; --- 1935,1940 ---- Py_DECREF(klass); cPickle_ErrFormat(PicklingError, ! "Can't pickle %s: it's not the same object " ! "as %s.%s", "OSS", args, module, global_name); goto finally; *************** *** 1938,1941 **** --- 1942,2002 ---- Py_DECREF(klass); + if (self->proto >= 2) { + /* See whether this is in the extension registry, and if + * so generate an EXT opcode. + */ + PyObject *py_code; /* extension code as Python object */ + long code; /* extensoin code as C value */ + char c_str[5]; + int n; + + PyTuple_SET_ITEM(two_tuple, 0, module); + PyTuple_SET_ITEM(two_tuple, 1, global_name); + py_code = PyDict_GetItem(extension_registry, two_tuple); + if (py_code == NULL) + goto gen_global; /* not registered */ + + /* Verify py_code has the right type and value. */ + if (!PyInt_Check(py_code)) { + cPickle_ErrFormat(PicklingError, "Can't pickle %s: " + "extension code %s isn't n integer", + "OO", args, py_code); + goto finally; + } + code = PyInt_AS_LONG(py_code); + if (code <= 0 || code > 0x7fffffffL) { + cPickle_ErrFormat(PicklingError, "Can't pickle %s: " + "extension code %ld is out of range", + "Ol", args, code); + goto finally; + } + + /* Generate an EXT opcode. */ + if (code <= 0xff) { + c_str[0] = EXT1; + c_str[1] = (char)code; + n = 2; + } + else if (code <= 0xffff) { + c_str[0] = EXT2; + c_str[1] = (char)(code & 0xff); + c_str[2] = (char)((code >> 8) & 0xff); + n = 3; + } + else { + c_str[0] = EXT4; + c_str[1] = (char)(code & 0xff); + c_str[2] = (char)((code >> 8) & 0xff); + c_str[3] = (char)((code >> 16) & 0xff); + c_str[4] = (char)((code >> 24) & 0xff); + n = 5; + } + + if (self->write_func(self, c_str, n) >= 0) + res = 0; + goto finally; /* and don't memoize */ + } + + gen_global: if (self->write_func(self, &global, 1) < 0) goto finally; *************** *** 5214,5218 **** Py_DECREF(copy_reg); ! if (!( empty_tuple = PyTuple_New(0))) return -1; --- 5275,5283 ---- Py_DECREF(copy_reg); ! if (!(empty_tuple = PyTuple_New(0))) ! return -1; ! ! two_tuple = PyTuple_New(2); ! if (two_tuple == NULL) return -1; From tim_one@users.sourceforge.net Tue Feb 4 21:47:53 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 04 Feb 2003 13:47:53 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.124,2.125 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv31627/Modules Modified Files: cPickle.c Log Message: cPickle: exempt two_tuple from GC -- it's a speed hack, and doesn't guarantee to keep valid pointers in its slots. tests: Moved ExtensionSaver from test_copy_reg into pickletester, and use it both places. Once extension codes get assigned, it won't be safe to overwrite them willy nilly in test suites, and ExtensionSaver does a thorough job of undoing any possible damage. Beefed up the EXT[124] tests a bit, to check the smallest and largest codes in each opcode's range too. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.124 retrieving revision 2.125 diff -C2 -d -r2.124 -r2.125 *** cPickle.c 4 Feb 2003 20:56:09 -0000 2.124 --- cPickle.c 4 Feb 2003 21:47:44 -0000 2.125 *************** *** 1947,1951 **** */ PyObject *py_code; /* extension code as Python object */ ! long code; /* extensoin code as C value */ char c_str[5]; int n; --- 1947,1951 ---- */ PyObject *py_code; /* extension code as Python object */ ! long code; /* extension code as C value */ char c_str[5]; int n; *************** *** 5281,5284 **** --- 5281,5289 ---- if (two_tuple == NULL) return -1; + /* We use this temp container with no regard to refcounts, or to + * keeping containees alive. Exempt from GC, because we don't + * want anything looking at two_tuple() by magic. + */ + PyObject_GC_UnTrack(two_tuple); /* Ugh */ From tim_one@users.sourceforge.net Tue Feb 4 21:48:18 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 04 Feb 2003 13:48:18 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.43,1.44 test_copy_reg.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv31627/Lib/test Modified Files: pickletester.py test_copy_reg.py Log Message: cPickle: exempt two_tuple from GC -- it's a speed hack, and doesn't guarantee to keep valid pointers in its slots. tests: Moved ExtensionSaver from test_copy_reg into pickletester, and use it both places. Once extension codes get assigned, it won't be safe to overwrite them willy nilly in test suites, and ExtensionSaver does a thorough job of undoing any possible damage. Beefed up the EXT[124] tests a bit, to check the smallest and largest codes in each opcode's range too. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -d -r1.43 -r1.44 *** pickletester.py 4 Feb 2003 20:56:08 -0000 1.43 --- pickletester.py 4 Feb 2003 21:47:43 -0000 1.44 *************** *** 2,5 **** --- 2,6 ---- import pickle import pickletools + import copy_reg from test.test_support import TestFailed, have_unicode, TESTFN *************** *** 18,21 **** --- 19,53 ---- return False + # We can't very well test the extension registry without putting known stuff + # in it, but we have to be careful to restore its original state. Code + # should do this: + # + # e = ExtensionSaver(extension_code) + # try: + # fiddle w/ the extension registry's stuff for extension_code + # finally: + # e.restore() + + class ExtensionSaver: + # Remember current registration for code (if any), and remove it (if + # there is one). + def __init__(self, code): + self.code = code + if code in copy_reg._inverted_registry: + self.pair = copy_reg._inverted_registry[code] + copy_reg.remove_extension(self.pair[0], self.pair[1], code) + else: + self.pair = None + + # Restore previous registration for code. + def restore(self): + code = self.code + curpair = copy_reg._inverted_registry.get(code) + if curpair is not None: + copy_reg.remove_extension(curpair[0], curpair[1], code) + pair = self.pair + if pair is not None: + copy_reg.add_extension(pair[0], pair[1], code) + class C: def __cmp__(self, other): *************** *** 587,594 **** # an object of that type. Check that the resulting pickle uses opcode # (EXT[124]) under proto 2, and not in proto 1. def produce_global_ext(self, extcode, opcode): ! import copy_reg ! copy_reg.add_extension(__name__, "MyList", extcode) try: x = MyList([1, 2, 3]) x.foo = 42 --- 619,627 ---- # an object of that type. Check that the resulting pickle uses opcode # (EXT[124]) under proto 2, and not in proto 1. + def produce_global_ext(self, extcode, opcode): ! e = ExtensionSaver(extcode) try: + copy_reg.add_extension(__name__, "MyList", extcode) x = MyList([1, 2, 3]) x.foo = 42 *************** *** 597,626 **** # Dump using protocol 1 for comparison. s1 = self.dumps(x, 1) y = self.loads(s1) self.assertEqual(list(x), list(y)) self.assertEqual(x.__dict__, y.__dict__) - self.assert_(s1.find(__name__) >= 0) - self.assert_(s1.find("MyList") >= 0) # Dump using protocol 2 for test. s2 = self.dumps(x, 2) ! self.assertEqual(s2.find(__name__), -1) ! self.assertEqual(s2.find("MyList"), -1) y = self.loads(s2) self.assertEqual(list(x), list(y)) self.assertEqual(x.__dict__, y.__dict__) - self.assertEqual(opcode_in_pickle(opcode, s2), True) finally: ! copy_reg.remove_extension(__name__, "MyList", extcode) def test_global_ext1(self): ! self.produce_global_ext(0xf0, pickle.EXT1) def test_global_ext2(self): ! self.produce_global_ext(0xfff0, pickle.EXT2) def test_global_ext4(self): ! self.produce_global_ext(0xabcdef0, pickle.EXT4) # XXX Temporary hack, so long as the C implementation of pickle protocol --- 630,668 ---- # Dump using protocol 1 for comparison. s1 = self.dumps(x, 1) + self.assert_(__name__ in s1) + self.assert_("MyList" in s1) + self.assertEqual(opcode_in_pickle(opcode, s1), False) + y = self.loads(s1) self.assertEqual(list(x), list(y)) self.assertEqual(x.__dict__, y.__dict__) # Dump using protocol 2 for test. s2 = self.dumps(x, 2) ! self.assert_(__name__ not in s2) ! self.assert_("MyList" not in s2) ! self.assertEqual(opcode_in_pickle(opcode, s2), True) ! y = self.loads(s2) self.assertEqual(list(x), list(y)) self.assertEqual(x.__dict__, y.__dict__) finally: ! e.restore() def test_global_ext1(self): ! self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code ! self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code def test_global_ext2(self): ! self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code ! self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code ! self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness def test_global_ext4(self): ! self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code ! self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code ! self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness ! # XXX Temporary hack, so long as the C implementation of pickle protocol Index: test_copy_reg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_copy_reg.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_copy_reg.py 4 Feb 2003 17:49:36 -0000 1.6 --- test_copy_reg.py 4 Feb 2003 21:47:43 -0000 1.7 *************** *** 1,31 **** import copy_reg import unittest - from test import test_support class C: pass - - class ExtensionSaver: - # Remember current registration for code (if any), and remove it (if - # there is one). - def __init__(self, code): - self.code = code - if code in copy_reg._inverted_registry: - self.pair = copy_reg._inverted_registry[code] - copy_reg.remove_extension(self.pair[0], self.pair[1], code) - else: - self.pair = None - - # Restore previous registration for code. - def restore(self): - code = self.code - curpair = copy_reg._inverted_registry.get(code) - if curpair is not None: - copy_reg.remove_extension(curpair[0], curpair[1], code) - pair = self.pair - if pair is not None: - copy_reg.add_extension(pair[0], pair[1], code) class CopyRegTestCase(unittest.TestCase): --- 1,11 ---- import copy_reg import unittest + from test import test_support + from test.pickletester import ExtensionSaver class C: pass class CopyRegTestCase(unittest.TestCase): From montanaro@users.sourceforge.net Tue Feb 4 22:10:57 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Tue, 04 Feb 2003 14:10:57 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv11868 Modified Files: test_csv.py Log Message: myexceltsv needs to subclass csv.excel, not csv.Dialect. doh! Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** test_csv.py 3 Feb 2003 20:26:26 -0000 1.14 --- test_csv.py 4 Feb 2003 22:10:54 -0000 1.15 *************** *** 216,220 **** def test_dialect_class(self): ! class myexceltsv(csv.Dialect): delimiter = "\t" fileobj = StringIO() --- 216,220 ---- def test_dialect_class(self): ! class myexceltsv(csv.excel): delimiter = "\t" fileobj = StringIO() From andrewmcnamara@users.sourceforge.net Wed Feb 5 00:45:41 2003 From: andrewmcnamara@users.sourceforge.net (andrewmcnamara@users.sourceforge.net) Date: Tue, 04 Feb 2003 16:45:41 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv8594 Modified Files: csv.py Log Message: Import the C module's __version__ symbol into the python module. Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** csv.py 3 Feb 2003 20:25:19 -0000 1.19 --- csv.py 5 Feb 2003 00:45:37 -0000 1.20 *************** *** 1,9 **** import _csv ! from _csv import Error __all__ = [ "QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", "Error", "Dialect", "excel", "excel_tab", "reader", "writer", "register_dialect", "get_dialect", "list_dialects", ! "unregister_dialect" ] QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE = range(4) --- 1,9 ---- import _csv ! from _csv import Error, __version__ __all__ = [ "QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", "Error", "Dialect", "excel", "excel_tab", "reader", "writer", "register_dialect", "get_dialect", "list_dialects", ! "unregister_dialect", "__version__" ] QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE = range(4) From montanaro@users.sourceforge.net Wed Feb 5 01:49:58 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Tue, 04 Feb 2003 17:49:58 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.13,1.14 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv28414 Modified Files: _csv.c Log Message: export QUOTE_* constants for use by csv.py Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** _csv.c 4 Feb 2003 14:54:54 -0000 1.13 --- _csv.c 5 Feb 2003 01:49:54 -0000 1.14 *************** *** 143,146 **** --- 143,147 ---- } + #if 0 static void parse_prepend_char(ParserObj *self, char c) *************** *** 152,155 **** --- 153,157 ---- self->field_len++; } + #endif static void *************** *** 940,943 **** --- 942,947 ---- PyObject *dict; PyObject *rev; + PyObject *v; + int res; if (PyType_Ready(&Parser_Type) < 0) *************** *** 957,960 **** --- 961,996 ---- return; if (PyDict_SetItemString(dict, "__version__", rev) < 0) + return; + + v = PyInt_FromLong(QUOTE_MINIMAL); + if (v == NULL) + return; + res = PyDict_SetItemString(dict, "QUOTE_MINIMAL", v); + Py_DECREF(v); + if (res < 0) + return; + + v = PyInt_FromLong(QUOTE_ALL); + if (v == NULL) + return; + res = PyDict_SetItemString(dict, "QUOTE_ALL", v); + Py_DECREF(v); + if (res < 0) + return; + + v = PyInt_FromLong(QUOTE_NONNUMERIC); + if (v == NULL) + return; + res = PyDict_SetItemString(dict, "QUOTE_NONNUMERIC", v); + Py_DECREF(v); + if (res < 0) + return; + + v = PyInt_FromLong(QUOTE_NONE); + if (v == NULL) + return; + res = PyDict_SetItemString(dict, "QUOTE_NONE", v); + Py_DECREF(v); + if (res < 0) return; From montanaro@users.sourceforge.net Wed Feb 5 01:53:21 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Tue, 04 Feb 2003 17:53:21 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv29985 Modified Files: csv.py Log Message: import QUOTE_* constants from low-level module Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** csv.py 5 Feb 2003 00:45:37 -0000 1.20 --- csv.py 5 Feb 2003 01:53:19 -0000 1.21 *************** *** 1,4 **** --- 1,5 ---- import _csv from _csv import Error, __version__ + from _csv import QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE __all__ = [ "QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", *************** *** 6,11 **** "register_dialect", "get_dialect", "list_dialects", "unregister_dialect", "__version__" ] - - QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE = range(4) _dialects = {} --- 7,10 ---- From montanaro@users.sourceforge.net Wed Feb 5 02:21:44 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Tue, 04 Feb 2003 18:21:44 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv6964 Modified Files: csv.py Log Message: rearrange the Dialect class some more. I'm not sure this is the best way to do things. We can yank stuff out though. It gives us something to argue about. ;-) * Make the Dialect class patently invalid. * Put excel's settings in the excel class. * Add a _name attribute to Dialect which is filled in by register_dialect(). * Add a _validate method which is called from __init__. Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** csv.py 5 Feb 2003 01:53:19 -0000 1.21 --- csv.py 5 Feb 2003 02:21:42 -0000 1.22 *************** *** 13,18 **** if not issubclass(dialect, Dialect): raise TypeError, "dialect not a subclass of Dialect" dialect._name = name ! _dialects[name] = dialect() def get_dialect(name): --- 13,21 ---- if not issubclass(dialect, Dialect): raise TypeError, "dialect not a subclass of Dialect" + if dialect == Dialect: + raise ValueError, "Dialect is an abstract class" + d = dialect() dialect._name = name ! _dialects[name] = d def get_dialect(name): *************** *** 27,40 **** class Dialect: _name = "" delimiter = ',' quotechar = '"' - escapechar = None doublequote = True skipinitialspace = False lineterminator = '\r\n' quoting = QUOTE_MINIMAL - - class excel(Dialect): - pass register_dialect("excel", excel) --- 30,73 ---- class Dialect: _name = "" + _valid = False + # placeholders + delimiter = None + quotechar = None + escapechar = None + doublequote = None + skipinitialspace = None + lineterminator = None + quoting = None + + def __init__(self): + if self.__class__ != Dialect: + self._valid = True + errors = self._validate() + if errors != []: + raise Error, "Dialect did not validate: %s" % ", ".join(errors) + + def _validate(self): + errors = [] + if not self._valid: + errors.append("can't directly instantiate Dialect class") + if self.delimiter is None: + errors.append("delimiter not set") + if self.quotechar is None: + errors.append("quotechar not set") + if self.lineterminator is None: + errors.append("lineterminator not set") + if self.doublequote not in (True, False): + errors.append("doublequote setting must be True or False") + if self.skipinitialspace not in (True, False): + errors.append("skipinitialspace setting must be True or False") + return errors + + class excel(Dialect): delimiter = ',' quotechar = '"' doublequote = True skipinitialspace = False lineterminator = '\r\n' quoting = QUOTE_MINIMAL register_dialect("excel", excel) From montanaro@users.sourceforge.net Wed Feb 5 02:22:12 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Tue, 04 Feb 2003 18:22:12 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv7157 Modified Files: test_csv.py Log Message: add a test for incomplete dialects Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** test_csv.py 4 Feb 2003 22:10:54 -0000 1.15 --- test_csv.py 5 Feb 2003 02:22:10 -0000 1.16 *************** *** 215,218 **** --- 215,223 ---- "myexceltsv", myexceltsv) + def test_incomplete_dialect(self): + class myexceltsv(csv.Dialect): + delimiter = "\t" + self.assertRaises(csv.Error, myexceltsv) + def test_dialect_class(self): class myexceltsv(csv.excel): From andrewmcnamara@users.sourceforge.net Wed Feb 5 03:20:54 2003 From: andrewmcnamara@users.sourceforge.net (andrewmcnamara@users.sourceforge.net) Date: Tue, 04 Feb 2003 19:20:54 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.14,1.15 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv24979 Modified Files: _csv.c Log Message: Raise an exception if quotechar is None and quoting attribute is set to a value that requires a quotechar. Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** _csv.c 5 Feb 2003 01:49:54 -0000 1.14 --- _csv.c 5 Feb 2003 03:20:51 -0000 1.15 *************** *** 736,739 **** --- 736,743 ---- return -1; } + if (!self->have_quotechar && n != QUOTE_NONE) { + PyErr_BadArgument(); + return -1; + } if (n == QUOTE_NONE) self->have_quotechar = 0; From andrewmcnamara@users.sourceforge.net Wed Feb 5 03:21:42 2003 From: andrewmcnamara@users.sourceforge.net (andrewmcnamara@users.sourceforge.net) Date: Tue, 04 Feb 2003 19:21:42 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.16,1.17 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv25230/test Modified Files: test_csv.py Log Message: Added a bunch of tests to get better coverage of the underlying _csv module. Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** test_csv.py 5 Feb 2003 02:22:10 -0000 1.16 --- test_csv.py 5 Feb 2003 03:21:39 -0000 1.17 *************** *** 6,9 **** --- 6,125 ---- from StringIO import StringIO import csv + import _csv + + class Test_Csv(unittest.TestCase): + """ + Test the underlying C csv parser in ways that are not appropriate + from the high level interface. + """ + def test_init(self): + "test that the module returns a parser" + parser = _csv.parser() + self.failUnless(hasattr(parser, 'parse')) + + def test_parameter_validation(self): + self.assertRaises(TypeError, _csv.parser, FlibbleWort = 0) + self.assertRaises(ValueError, _csv.parser, quoting = -1) + self.assertRaises(ValueError, _csv.parser, quoting = csv.QUOTE_NONE + 1) + self.assertRaises(TypeError, _csv.parser, delimiter = None) + self.assertRaises(TypeError, _csv.parser, skipinitialspace = None) + + def test_parameter(self): + parser = _csv.parser(delimiter = "\t") + self.assertEqual(parser.delimiter, "\t") + + parser = _csv.parser(quotechar = "'") + self.assertEqual(parser.quotechar, "'") + + parser = _csv.parser(quoting = csv.QUOTE_NONE) + self.assertEqual(parser.quotechar, None) + + parser = _csv.parser(quotechar=None,quoting=csv.QUOTE_ALL) + self.assertEqual(parser.quoting, csv.QUOTE_NONE) + + def test_attr_validation(self): + parser = _csv.parser() + self.assertRaises(AttributeError, delattr, parser, 'quoting') + self.assertRaises(TypeError, setattr, parser, 'quoting', -1) + self.assertRaises(TypeError, setattr, parser, 'quoting', + csv.QUOTE_NONE + 1) + self.assertRaises(TypeError, setattr, parser, 'quotechar', 0) + self.assertRaises(TypeError, setattr, parser, 'escapechar', 0) + parser.quotechar=None + self.assertRaises(TypeError, setattr, parser, 'quoting', 1) + self.assertRaises(TypeError, setattr, parser, 'lineterminator', None) + + def test_setattr(self): + parser = _csv.parser() + parser.delimiter = "\t" + self.assertEqual(parser.delimiter, "\t") + + parser = _csv.parser() + parser.quotechar = "'" + self.assertEqual(parser.quotechar, "'") + + parser = _csv.parser() + parser.quoting = csv.QUOTE_NONE + self.assertEqual(parser.quotechar, None) + + def test_join_bigfield(self): + # This exercises the buffer realloc functionality + parser = _csv.parser() + bigstring = 'X' * 50000 + result = parser.join([bigstring,bigstring]) + self.assertEqual(result, '%s,%s%s' % \ + (bigstring, bigstring, parser.lineterminator)) + + def test_join_quoting(self): + parser = _csv.parser() + self.assertEqual(parser.join(['a','1','p,q']), 'a,1,"p,q"\r\n') + parser = _csv.parser(quoting = csv.QUOTE_NONE) + self.assertRaises(_csv.Error, parser.join, ['a','1','p,q']) + parser = _csv.parser(quoting = csv.QUOTE_MINIMAL) + self.assertEqual(parser.join(['a','1','p,q']), 'a,1,"p,q"\r\n') + parser = _csv.parser(quoting = csv.QUOTE_NONNUMERIC) + self.assertEqual(parser.join(['a','1','p,q']), '"a",1,"p,q"\r\n') + parser = _csv.parser(quoting = csv.QUOTE_ALL) + self.assertEqual(parser.join(['a','1','p,q']), '"a","1","p,q"\r\n') + + def test_join_escape(self): + parser = _csv.parser(escapechar='\\') + self.assertEqual(parser.join(['a','1','p,q']), 'a,1,"p,q"\r\n') + parser.doublequote = 0 + # FAIL - need to fix + # self.assertEqual(parser.join(['a','1','p,"q"']), 'a,1,"p,\\"q"\r\n') + parser.quotechar = None + self.assertEqual(parser.join(['a','1','p,q']), 'a,1,p\\,q\r\n') + + def test_parse(self): + parser = _csv.parser() + self.assertRaises(TypeError, parser.parse, None) + self.assertEqual(parser.parse(''), []) + + def test_parse_eol(self): + parser = _csv.parser() + self.assertEqual(parser.parse('a,b'), ['a','b']) + self.assertEqual(parser.parse('a,b\n'), ['a','b']) + self.assertEqual(parser.parse('a,b\r\n'), ['a','b']) + self.assertEqual(parser.parse('a,b\r'), ['a','b']) + self.assertRaises(csv.Error, parser.parse, 'a,b\rc,d') + self.assertRaises(csv.Error, parser.parse, 'a,b\nc,d') + self.assertRaises(csv.Error, parser.parse, 'a,b\r\nc,d') + + def test_parse_escape(self): + parser = _csv.parser(escapechar='\\') + self.assertEqual(parser.parse('a,\\b,c'), ['a', '\\b', 'c']) + self.assertEqual(parser.parse('a,b\\,c'), ['a', 'b,c']) + self.assertEqual(parser.parse('a,"b\\,c"'), ['a', 'b,c']) + self.assertEqual(parser.parse('a,"b,\\c"'), ['a', 'b,\\c']) + self.assertEqual(parser.parse('a,"b,c\\""'), ['a', 'b,c"']) + self.assertEqual(parser.parse('a,"b,c"\\'), ['a', 'b,c\\']) + + def test_parse_bigfield(self): + # This exercises the buffer realloc functionality + parser = _csv.parser() + bigstring = 'X' * 50000 + bigline = '%s,%s%s' % (bigstring, bigstring, parser.lineterminator) + self.assertEqual(parser.parse(bigline), [bigstring, bigstring]) class TestCsvBase(unittest.TestCase): From tim_one@users.sourceforge.net Wed Feb 5 03:46:19 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 04 Feb 2003 19:46:19 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.125,2.126 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv32596/Modules Modified Files: cPickle.c Log Message: Typo repair. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.125 retrieving revision 2.126 diff -C2 -d -r2.125 -r2.126 *** cPickle.c 4 Feb 2003 21:47:44 -0000 2.125 --- cPickle.c 5 Feb 2003 03:46:17 -0000 2.126 *************** *** 1481,1485 **** /* A helper for save_tuple. Push the len elements in tuple t on the stack. */ static int ! store_tuple_elememts(Picklerobject *self, PyObject *t, int len) { int i; --- 1481,1485 ---- /* A helper for save_tuple. Push the len elements in tuple t on the stack. */ static int ! store_tuple_elements(Picklerobject *self, PyObject *t, int len) { int i; *************** *** 1504,1508 **** /* Tuples are ubiquitous in the pickle protocols, so many techniques are * used across protocols to minimize the space needed to pickle them. ! * Tuples are also the only builtin immuatable type that can be recursive * (a tuple can be reached from itself), and that requires some subtle * magic so that it works in all cases. IOW, this is a long routine. --- 1504,1508 ---- /* Tuples are ubiquitous in the pickle protocols, so many techniques are * used across protocols to minimize the space needed to pickle them. ! * Tuples are also the only builtin immutable type that can be recursive * (a tuple can be reached from itself), and that requires some subtle * magic so that it works in all cases. IOW, this is a long routine. *************** *** 1554,1558 **** if (len <= 3 && self->proto >= 2) { /* Use TUPLE{1,2,3} opcodes. */ ! if (store_tuple_elememts(self, args, len) < 0) goto finally; if (PyDict_GetItem(self->memo, py_tuple_id)) { --- 1554,1558 ---- if (len <= 3 && self->proto >= 2) { /* Use TUPLE{1,2,3} opcodes. */ ! if (store_tuple_elements(self, args, len) < 0) goto finally; if (PyDict_GetItem(self->memo, py_tuple_id)) { *************** *** 1579,1583 **** goto finally; ! if (store_tuple_elememts(self, args, len) < 0) goto finally; --- 1579,1583 ---- goto finally; ! if (store_tuple_elements(self, args, len) < 0) goto finally; From tim_one@users.sourceforge.net Wed Feb 5 03:53:13 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 04 Feb 2003 19:53:13 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.126,2.127 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv2551/Modules Modified Files: cPickle.c Log Message: More typo repair. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.126 retrieving revision 2.127 diff -C2 -d -r2.126 -r2.127 *** cPickle.c 5 Feb 2003 03:46:17 -0000 2.126 --- cPickle.c 5 Feb 2003 03:53:10 -0000 2.127 *************** *** 1960,1964 **** if (!PyInt_Check(py_code)) { cPickle_ErrFormat(PicklingError, "Can't pickle %s: " ! "extension code %s isn't n integer", "OO", args, py_code); goto finally; --- 1960,1964 ---- if (!PyInt_Check(py_code)) { cPickle_ErrFormat(PicklingError, "Can't pickle %s: " ! "extension code %s isn't an integer", "OO", args, py_code); goto finally; From tim_one@users.sourceforge.net Wed Feb 5 04:08:19 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 04 Feb 2003 20:08:19 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv7682/Lib/test Modified Files: test_datetime.py Log Message: Build pickler_choices list in a lazier way. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** test_datetime.py 3 Feb 2003 01:32:33 -0000 1.34 --- test_datetime.py 5 Feb 2003 04:08:07 -0000 1.35 *************** *** 17,36 **** from datetime import date, datetime ! ! pickle_choices = [ ! (pickle, pickle, 0), ! (pickle, pickle, 1), ! (pickle, pickle, 2), ! (cPickle, cPickle, 0), ! (cPickle, cPickle, 1), ! (cPickle, cPickle, 2), ! (pickle, cPickle, 0), ! (pickle, cPickle, 1), ! (pickle, cPickle, 2), ! (cPickle, pickle, 0), ! (cPickle, pickle, 1), ! (cPickle, pickle, 2), ! ] ! # XXX The test suite uncovered a bug in Python 2.2.2: if x and y are --- 17,25 ---- from datetime import date, datetime ! pickle_choices = [(pickler, unpickler, proto) ! for pickler in pickle, cPickle ! for unpickler in pickle, cPickle ! for proto in range(3)] ! assert len(pickle_choices) == 2*2*3 # XXX The test suite uncovered a bug in Python 2.2.2: if x and y are From rhettinger@users.sourceforge.net Wed Feb 5 04:12:44 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue, 04 Feb 2003 20:12:44 -0800 Subject: [Python-checkins] python/dist/src/Lib/bsddb dbobj.py,1.3,1.4 dbshelve.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/bsddb In directory sc8-pr-cvs1:/tmp/cvs-serv8663 Modified Files: dbobj.py dbshelve.py Log Message: SF patch #674396: Apply UserDict.DictMixin to expand dbshelve and dbojb to have a full dictionary interface. Index: dbobj.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/dbobj.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** dbobj.py 30 Dec 2002 20:52:07 -0000 1.3 --- dbobj.py 5 Feb 2003 04:12:41 -0000 1.4 *************** *** 17,20 **** --- 17,21 ---- import db + from UserDict import DictMixin class DBEnv: *************** *** 86,90 **** ! class DB: def __init__(self, dbenv, *args, **kwargs): # give it the proper DBEnv C object that its expecting --- 87,91 ---- ! class DB(DictMixin): def __init__(self, dbenv, *args, **kwargs): # give it the proper DBEnv C object that its expecting Index: dbshelve.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/dbshelve.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** dbshelve.py 28 Jan 2003 17:20:42 -0000 1.5 --- dbshelve.py 5 Feb 2003 04:12:41 -0000 1.6 *************** *** 31,34 **** --- 31,35 ---- import cPickle + from UserDict import DictMixin try: # For Python 2.3 *************** *** 76,80 **** #--------------------------------------------------------------------------- ! class DBShelf: """ A shelf to hold pickled objects, built upon a bsddb DB object. It --- 77,81 ---- #--------------------------------------------------------------------------- ! class DBShelf(DictMixin): """ A shelf to hold pickled objects, built upon a bsddb DB object. It From andrea" ------=_NextPart_000_00D6_16E36C1E.E3312C73 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: base64 KiBSZWR1Y2UgdGhlIGFtb3VudCBvZiBzbGVlcCB5b3UgbmVlZA0KKiBDYXVz ZSB3b3VuZHMgdG8gaGVhbCBmYXN0ZXINCiogTG9zZSB3ZWlnaHQgd2hpbGUg eW91ciBzbGVlcGluZw0KKiBCZWNvbWUgbGVzcyB3aW5kZWQgd2hlbiBleGNl cnNpemluZw0KKiBQdXQgY29sb3IgYmFjayBpbiBncmV5IGhhaXINCiogR3Jv dyBoYWlyIGJhY2sgd2hlcmUgaXQgaGFkIG9uY2UgZmFsbGVuIG91dA0KKiBU aWdodGVuIHNraW4NCiogU3RyZW5ndGhlbiBib25lcw0KKiBCb2R5IGJ1aWxk ZXJzIC0gdXNlIHRoaXMgdG8gYnVpbGQgeW91ciBtdXNjbGVzIHF1aWNrZXIN Ci4uLi4uLi4uLi5UaGUgTGlzdCB0cnVseSBnb2VzIG9uIGFuZCBvbi4uLi4u Li4uLi4NCg0KQXMgc2VlbiBvbiBOQkMsIENCUywgQ05OLCBhbmQgT3ByYWgh IFRoZSBoZWFsdGggZGlzY292ZXJ5IA0KdGhhdCBhY3R1YWxseSByZXZlcnNl cyBhZ2luZyBzeW1wdG9tcyB3aXRob3V0IGRpZXRpbmcgb3IgZXhlcmNpc2Uh IA0KVGhpcyBQUk9WRU4gZGlzY292ZXJ5IGhhcyBiZWVuIHJlcG9ydGVkIG9u IGJ5IHRoZSANCk5ldyBFbmdsYW5kIEpvdXJuYWwgb2YgTWVkaWNpbmUgLSBk b24ndCBqdXN0IHRha2Ugb3VyIHdvcmQgZm9yIGl0Lg0KDQpJbiBmYWN0IHdl J2QgbGlrZSB5b3UgdG8gcmVjZWl2ZSBhIEYuUi5FLkUgdGhpcnR5IGRheSBz dXBwbHk7IGxvb2sgYW5kIGZlZWwgDQp5b3VuZ2VyLCBsb3NlIHdlaWdodCwg cmVkdWNlIHNsZWVwLCBUaGUgbGlzdCBnb2VzIG9uLCB3ZSANCmVuY291cmFn ZSB5b3UgdG8gYXQgbGVhc3QgdGFrZSBhIGxvb2sgYXQgdGhlIGluZm9ybWF0 aW9uIGFzIHRvDQp3aGF0IGVsc2UgaXQgY2FuIGRvDQoNCmh0dHA6Ly9oaWRk ZW4uY29tLm1zLXNjcmlwdC42NTE2ODUuOTg3MzY2MS0wMzMyMTk4NzYzNTEz NTMxODQxLmVuY29kZS4zMzM3MTgxNTA3NDYwNTU2NC5lbHNlLjE0MDU1ODYz NzIwMjU4OTQ2MzAyMTU1MDYzNzMyLm1zL3d3dy5ncm93eW91bmcuY29tLz9s aWZlcw0KDQoNCjc3OTB5RmFpNy01OTJCd3BtNzA3N3dNbXQ0LTgzM2tBWnYz MjU1bDM2 From davecole@users.sourceforge.net Wed Feb 5 10:30:09 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Wed, 05 Feb 2003 02:30:09 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.15,1.16 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv30447 Modified Files: _csv.c Log Message: Replace the cut & paste QUOTE_* code in module init with a loop. Removed the have_quotechar attribute and use quoting == QUOTE_NONE instead. Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** _csv.c 5 Feb 2003 03:20:51 -0000 1.15 --- _csv.c 5 Feb 2003 10:30:06 -0000 1.16 *************** *** 50,58 **** typedef struct { PyObject_HEAD int doublequote; /* is " represented by ""? */ char delimiter; /* field separator */ - int have_quotechar; /* is a quotechar defined */ char quotechar; /* quote character */ int have_escapechar; /* is an escapechar defined */ --- 50,70 ---- typedef struct { + QuoteStyle style; + char *name; + } StyleDesc; + + static StyleDesc quote_styles[] = { + { QUOTE_MINIMAL, "QUOTE_MINIMAL" }, + { QUOTE_ALL, "QUOTE_ALL" }, + { QUOTE_NONNUMERIC, "QUOTE_NONNUMERIC" }, + { QUOTE_NONE, "QUOTE_NONE" }, + { 0 } + }; + + typedef struct { PyObject_HEAD int doublequote; /* is " represented by ""? */ char delimiter; /* field separator */ char quotechar; /* quote character */ int have_escapechar; /* is an escapechar defined */ *************** *** 262,266 **** case QUOTE_IN_QUOTED_FIELD: /* doublequote - seen a quote in an quoted field */ ! if (self->have_quotechar && c == self->quotechar) { /* save "" as " */ parse_add_char(self, c); --- 274,278 ---- case QUOTE_IN_QUOTED_FIELD: /* doublequote - seen a quote in an quoted field */ ! if (self->quoting != QUOTE_NONE && c == self->quotechar) { /* save "" as " */ parse_add_char(self, c); *************** *** 447,451 **** * quote. */ ! if (self->have_quotechar && c == self->quotechar && self->doublequote) { if (copy_phase) --- 459,463 ---- * quote. */ ! if (self->quoting != QUOTE_NONE && c == self->quotechar && self->doublequote) { if (copy_phase) *************** *** 464,469 **** && (c == self->delimiter || c == self->escapechar || c == '\n' || c == '\r')) { ! if (self->have_quotechar ! && self->quoting != QUOTE_NONE) *quoted = 1; else if (self->escapechar) { --- 476,480 ---- && (c == self->delimiter || c == self->escapechar || c == '\n' || c == '\r')) { ! if (self->quoting != QUOTE_NONE) *quoted = 1; else if (self->escapechar) { *************** *** 486,491 **** /* If field is empty check if it needs to be quoted. */ ! if (i == 0 && quote_empty && self->have_quotechar) ! *quoted = 1; /* Handle final quote character on field. --- 497,507 ---- /* If field is empty check if it needs to be quoted. */ ! if (i == 0 && quote_empty) { ! if (self->quoting == QUOTE_NONE) { ! raise_exception("single empty field record must be quoted"); ! return -1; ! } else ! *quoted = 1; ! } /* Handle final quote character on field. *************** *** 679,684 **** PyObject *rv; ! if ((strcmp(name, "quotechar") == 0 && !self->have_quotechar) ! || (strcmp(name, "escapechar") == 0 && !self->have_escapechar)) { Py_INCREF(Py_None); return Py_None; --- 695,699 ---- PyObject *rv; ! if (strcmp(name, "escapechar") == 0 && !self->have_escapechar) { Py_INCREF(Py_None); return Py_None; *************** *** 723,730 **** return -1; } ! if (strcmp(name, "quotechar") == 0) ! return _set_char_attr(&self->quotechar, ! &self->have_quotechar, v); ! else if (strcmp(name, "escapechar") == 0) return _set_char_attr(&self->escapechar, &self->have_escapechar, v); --- 738,742 ---- return -1; } ! if (strcmp(name, "escapechar") == 0) return _set_char_attr(&self->escapechar, &self->have_escapechar, v); *************** *** 736,745 **** return -1; } - if (!self->have_quotechar && n != QUOTE_NONE) { - PyErr_BadArgument(); - return -1; - } - if (n == QUOTE_NONE) - self->have_quotechar = 0; self->quoting = n; return 0; --- 748,751 ---- *************** *** 834,838 **** NULL }; ! PyObject *quotechar, *escapechar; ParserObj *self = PyObject_NEW(ParserObj, &Parser_Type); --- 840,844 ---- NULL }; ! PyObject *escapechar; ParserObj *self = PyObject_NEW(ParserObj, &Parser_Type); *************** *** 841,845 **** self->quotechar = '"'; - self->have_quotechar = 1; self->delimiter = ','; self->escapechar = '\0'; --- 847,850 ---- *************** *** 869,882 **** self->num_fields = 0; ! quotechar = escapechar = NULL; ! if (PyArg_ParseTupleAndKeywords(args, keyword_args, "|OcOiSiiii", keywords, ! "echar, &self->delimiter, &escapechar, &self->skipinitialspace, &self->lineterminator, &self->quoting, &self->doublequote, &self->autoclear, &self->strict) - && !_set_char_attr(&self->quotechar, - &self->have_quotechar, quotechar) && !_set_char_attr(&self->escapechar, &self->have_escapechar, escapechar)) { --- 874,885 ---- self->num_fields = 0; ! escapechar = NULL; ! if (PyArg_ParseTupleAndKeywords(args, keyword_args, "|ccOiSiiii", keywords, ! &self->quotechar, &self->delimiter, &escapechar, &self->skipinitialspace, &self->lineterminator, &self->quoting, &self->doublequote, &self->autoclear, &self->strict) && !_set_char_attr(&self->escapechar, &self->have_escapechar, escapechar)) { *************** *** 889,899 **** if (self->quoting < 0 || self->quoting > QUOTE_NONE) PyErr_SetString(PyExc_ValueError, "bad quoting value"); ! else { ! if (self->quoting == QUOTE_NONE) ! self->have_quotechar = 0; ! else if (!self->have_quotechar) ! self->quoting = QUOTE_NONE; return (PyObject*)self; - } } --- 892,897 ---- if (self->quoting < 0 || self->quoting > QUOTE_NONE) PyErr_SetString(PyExc_ValueError, "bad quoting value"); ! else return (PyObject*)self; } *************** *** 948,951 **** --- 946,950 ---- PyObject *v; int res; + StyleDesc *style; if (PyType_Ready(&Parser_Type) < 0) *************** *** 967,1001 **** return; ! v = PyInt_FromLong(QUOTE_MINIMAL); ! if (v == NULL) ! return; ! res = PyDict_SetItemString(dict, "QUOTE_MINIMAL", v); ! Py_DECREF(v); ! if (res < 0) ! return; ! ! v = PyInt_FromLong(QUOTE_ALL); ! if (v == NULL) ! return; ! res = PyDict_SetItemString(dict, "QUOTE_ALL", v); ! Py_DECREF(v); ! if (res < 0) ! return; ! ! v = PyInt_FromLong(QUOTE_NONNUMERIC); ! if (v == NULL) ! return; ! res = PyDict_SetItemString(dict, "QUOTE_NONNUMERIC", v); ! Py_DECREF(v); ! if (res < 0) ! return; ! ! v = PyInt_FromLong(QUOTE_NONE); ! if (v == NULL) ! return; ! res = PyDict_SetItemString(dict, "QUOTE_NONE", v); ! Py_DECREF(v); ! if (res < 0) ! return; /* Add the CSV exception object to the module. */ --- 966,979 ---- return; ! /* Add quote styles into disctionary */ ! for (style = quote_styles; style->name; style++) { ! v = PyInt_FromLong(style->style); ! if (v == NULL) ! return; ! res = PyDict_SetItemString(dict, style->name, v); ! Py_DECREF(v); ! if (res < 0) ! return; ! } /* Add the CSV exception object to the module. */ From jackjansen@users.sourceforge.net Wed Feb 5 11:14:18 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Feb 2003 03:14:18 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_macostools.py,1.2,1.3 test_macfs.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv12602 Modified Files: test_macostools.py test_macfs.py Log Message: Use os.path.realpath() in stead of abspath(), so the tests don't fail if we have a symlink somewhere in the TESTFN path. Index: test_macostools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_macostools.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_macostools.py 28 Jan 2003 23:54:05 -0000 1.2 --- test_macostools.py 5 Feb 2003 11:14:15 -0000 1.3 *************** *** 69,73 **** macostools.mkalias(test_support.TESTFN, TESTFN2) fss, _, _ = macfs.ResolveAliasFile(TESTFN2) ! self.assertEqual(fss.as_pathname(), os.path.abspath(test_support.TESTFN)) def test_mkalias_relative(self): --- 69,73 ---- macostools.mkalias(test_support.TESTFN, TESTFN2) fss, _, _ = macfs.ResolveAliasFile(TESTFN2) ! self.assertEqual(fss.as_pathname(), os.path.realpath(test_support.TESTFN)) def test_mkalias_relative(self): *************** *** 78,82 **** macostools.mkalias(test_support.TESTFN, TESTFN2, sys.prefix) fss, _, _ = macfs.ResolveAliasFile(TESTFN2) ! self.assertEqual(fss.as_pathname(), os.path.abspath(test_support.TESTFN)) --- 78,82 ---- macostools.mkalias(test_support.TESTFN, TESTFN2, sys.prefix) fss, _, _ = macfs.ResolveAliasFile(TESTFN2) ! self.assertEqual(fss.as_pathname(), os.path.realpath(test_support.TESTFN)) Index: test_macfs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_macfs.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_macfs.py 28 Jan 2003 21:39:28 -0000 1.1 --- test_macfs.py 5 Feb 2003 11:14:16 -0000 1.2 *************** *** 22,30 **** def test_fsspec(self): fss = macfs.FSSpec(test_support.TESTFN) ! self.assertEqual(os.path.abspath(test_support.TESTFN), fss.as_pathname()) def test_fsref(self): fsr = macfs.FSRef(test_support.TESTFN) ! self.assertEqual(os.path.abspath(test_support.TESTFN), fsr.as_pathname()) def test_coercion(self): --- 22,30 ---- def test_fsspec(self): fss = macfs.FSSpec(test_support.TESTFN) ! self.assertEqual(os.path.realpath(test_support.TESTFN), fss.as_pathname()) def test_fsref(self): fsr = macfs.FSRef(test_support.TESTFN) ! self.assertEqual(os.path.realpath(test_support.TESTFN), fsr.as_pathname()) def test_coercion(self): From jackjansen@users.sourceforge.net Wed Feb 5 13:36:32 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Feb 2003 05:36:32 -0800 Subject: [Python-checkins] python/dist/src/Mac/Build PythonCore.mcp,1.42,1.43 PythonStandSmall.mcp,1.48,1.49 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory sc8-pr-cvs1:/tmp/cvs-serv982 Modified Files: PythonCore.mcp PythonStandSmall.mcp Log Message: Added itertools module. Index: PythonCore.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonCore.mcp,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 Binary files /tmp/cvsofBHns and /tmp/cvs6dlIcM differ Index: PythonStandSmall.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonStandSmall.mcp,v retrieving revision 1.48 retrieving revision 1.49 diff -C2 -d -r1.48 -r1.49 Binary files /tmp/cvs0BdQWI and /tmp/cvs4Qs1ti differ From jackjansen@users.sourceforge.net Wed Feb 5 13:36:52 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Feb 2003 05:36:52 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules macconfig.c,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv1228 Modified Files: macconfig.c Log Message: Added itertools module. Index: macconfig.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/macconfig.c,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** macconfig.c 30 Dec 2002 23:11:30 -0000 1.37 --- macconfig.c 5 Feb 2003 13:36:50 -0000 1.38 *************** *** 178,181 **** --- 178,182 ---- extern void initxreadlines(); extern void initzipimport(); + extern void inititertools(); /* -- ADDMODULE MARKER 1 -- */ *************** *** 302,305 **** --- 303,307 ---- {"xreadlines", initxreadlines}, {"zipimport", initzipimport}, + {"itertools", inititertools}, /* -- ADDMODULE MARKER 2 -- */ From jackjansen@users.sourceforge.net Wed Feb 5 13:39:07 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Feb 2003 05:39:07 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac buildtools.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv2325 Modified Files: buildtools.py Log Message: Fixed a few typos, and changed FSCreateResourceFile filename argument to unicode. Index: buildtools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/buildtools.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** buildtools.py 2 Feb 2003 23:03:50 -0000 1.3 --- buildtools.py 5 Feb 2003 13:39:04 -0000 1.4 *************** *** 55,59 **** file, d1, d2 = Carbon.File.FSResolveAliasFile(file, 1) break ! except (Carbon.File.error, ValueError): continue else: --- 55,59 ---- file, d1, d2 = Carbon.File.FSResolveAliasFile(file, 1) break ! except (Carbon.File.Error, ValueError): continue else: *************** *** 176,180 **** except MacOS.Error: destdir, destfile = os.path.split(destname) ! Res.FSCreateResourceFile(destdir, destfile, RESOURCE_FORK_NAME) output = Res.FSOpenResourceFile(destname, RESOURCE_FORK_NAME, WRITE) --- 176,180 ---- except MacOS.Error: destdir, destfile = os.path.split(destname) ! Res.FSCreateResourceFile(destdir, unicode(destfile), RESOURCE_FORK_NAME) output = Res.FSOpenResourceFile(destname, RESOURCE_FORK_NAME, WRITE) *************** *** 262,266 **** # Now set the creator, type and bundle bit of the destination. # Done with FSSpec's, FSRef FInfo isn't good enough yet (2.3a1+) ! dset_fss = Carbon.File.FSSpec(destname) dest_finfo = dest_fss.FSpGetFInfo() dest_finfo.Creator = ownertype --- 262,266 ---- # Now set the creator, type and bundle bit of the destination. # Done with FSSpec's, FSRef FInfo isn't good enough yet (2.3a1+) ! dest_fss = Carbon.File.FSSpec(destname) dest_finfo = dest_fss.FSpGetFInfo() dest_finfo.Creator = ownertype From jlt63@users.sourceforge.net Wed Feb 5 15:16:21 2003 From: jlt63@users.sourceforge.net (jlt63@users.sourceforge.net) Date: Wed, 05 Feb 2003 07:16:21 -0800 Subject: [Python-checkins] python/dist/src setup.py,1.142,1.143 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv13582 Modified Files: setup.py Log Message: This patch reverts the following: It also prevents building against the real X headers, if installed. After discussions with the Cygwin project lead, I believe that building against the real X headers is OK. Especially, since the psuedo-X headers are *not* installed by the Cygwin Tcl/Tk binary package. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.142 retrieving revision 1.143 diff -C2 -d -r1.142 -r1.143 *** setup.py 5 Feb 2003 15:06:46 -0000 1.142 --- setup.py 5 Feb 2003 15:16:17 -0000 1.143 *************** *** 954,962 **** include_dirs.append('/usr/openwin/include') added_lib_dirs.append('/usr/openwin/lib') - elif platform == 'cygwin': - # Verify that the pseudo-X headers are installed before proceeding - x11_inc = find_file('X11/Xlib.h', [], inc_dirs) - if x11_inc is None: - return elif os.path.exists('/usr/X11R6/include'): include_dirs.append('/usr/X11R6/include') --- 954,957 ---- *************** *** 969,972 **** --- 964,973 ---- include_dirs.append('/usr/X11/include') added_lib_dirs.append('/usr/X11/lib') + + # If Cygwin, then verify that X is installed before proceeding + if platform == 'cygwin': + x11_inc = find_file('X11/Xlib.h', [], include_dirs) + if x11_inc is None: + return # Check for BLT extension From jlt63@users.sourceforge.net Wed Feb 5 15:06:54 2003 From: jlt63@users.sourceforge.net (jlt63@users.sourceforge.net) Date: Wed, 05 Feb 2003 07:06:54 -0800 Subject: [Python-checkins] python/dist/src setup.py,1.141,1.142 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv7952 Modified Files: setup.py Log Message: This patch enables Cygwin Python to build _tkinter against Tcl/Tk 8.4. Note that this patch just reverts the lib_prefix (i.e., "cyg") portion of my Tcl/Tk 8.3 patch. It seems that Cygwin Tcl/Tk is using a more normal file naming convention again. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.141 retrieving revision 1.142 diff -C2 -d -r1.141 -r1.142 *** setup.py 2 Feb 2003 17:59:05 -0000 1.141 --- setup.py 5 Feb 2003 15:06:46 -0000 1.142 *************** *** 916,925 **** return - # Set platform specific library prefix, if any - if platform == 'cygwin': - lib_prefix = 'cyg' - else: - lib_prefix = '' - # Assume we haven't found any of the libraries or include files # The versions with dots are used on Unix, and the versions without --- 916,919 ---- *************** *** 928,935 **** for version in ['8.4', '84', '8.3', '83', '8.2', '82', '8.1', '81', '8.0', '80']: ! tklib = self.compiler.find_library_file(lib_dirs, ! lib_prefix + 'tk' + version) ! tcllib = self.compiler.find_library_file(lib_dirs, ! lib_prefix + 'tcl' + version) if tklib and tcllib: # Exit the loop when we've found the Tcl/Tk libraries --- 922,927 ---- for version in ['8.4', '84', '8.3', '83', '8.2', '82', '8.1', '81', '8.0', '80']: ! tklib = self.compiler.find_library_file(lib_dirs, 'tk' + version) ! tcllib = self.compiler.find_library_file(lib_dirs, 'tcl' + version) if tklib and tcllib: # Exit the loop when we've found the Tcl/Tk libraries *************** *** 989,994 **** # Add the Tcl/Tk libraries ! libs.append(lib_prefix + 'tk'+ version) ! libs.append(lib_prefix + 'tcl'+ version) if platform in ['aix3', 'aix4']: --- 981,986 ---- # Add the Tcl/Tk libraries ! libs.append('tk'+ version) ! libs.append('tcl'+ version) if platform in ['aix3', 'aix4']: From jackjansen@users.sourceforge.net Wed Feb 5 15:40:09 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Feb 2003 07:40:09 -0800 Subject: [Python-checkins] python/dist/src/Mac/Tools/IDE Wbase.py,1.11,1.12 Wtext.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory sc8-pr-cvs1:/tmp/cvs-serv27987 Modified Files: Wbase.py Wtext.py Log Message: Cast various floats to ints so we don't get warnings. Index: Wbase.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/Wbase.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** Wbase.py 30 Nov 2002 00:01:27 -0000 1.11 --- Wbase.py 5 Feb 2003 15:40:04 -0000 1.12 *************** *** 402,406 **** def _darkencolor((r, g, b)): ! return 0.75 * r, 0.75 * g, 0.75 * b class BevelBox(Widget): --- 402,406 ---- def _darkencolor((r, g, b)): ! return int(0.75 * r), int(0.75 * g), int(0.75 * b) class BevelBox(Widget): Index: Wtext.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/Wtext.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** Wtext.py 30 Nov 2002 00:01:28 -0000 1.18 --- Wtext.py 5 Feb 2003 15:40:05 -0000 1.19 *************** *** 530,533 **** --- 530,534 ---- delta = min(maxdelta, delta) delta = max(mindelta, delta) + delta = int(delta) self.ted.WEScroll(0, delta) self.updatescrollbars() *************** *** 557,560 **** --- 558,562 ---- delta = min(maxdelta, delta) delta = max(mindelta, delta) + delta = int(delta) self.ted.WEScroll(delta, 0) self.updatescrollbars() From jackjansen@users.sourceforge.net Wed Feb 5 15:41:26 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Feb 2003 07:41:26 -0800 Subject: [Python-checkins] python/dist/src/Mac/Tools/IDE PythonIDEMain.py,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory sc8-pr-cvs1:/tmp/cvs-serv28271 Modified Files: PythonIDEMain.py Log Message: Added "Open File by Name" command which presens a filename dialog. If the clipboard contains a filename that filename is used as the default. Index: PythonIDEMain.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PythonIDEMain.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** PythonIDEMain.py 26 Jan 2003 22:15:48 -0000 1.25 --- PythonIDEMain.py 5 Feb 2003 15:41:09 -0000 1.26 *************** *** 71,74 **** --- 71,75 ---- newitem = FrameWork.MenuItem(m, "New", "N", 'new') openitem = FrameWork.MenuItem(m, "Open"+ELIPSES, "O", 'open') + openbynameitem = FrameWork.MenuItem(m, "Open File by Name"+ELIPSES, "D", 'openbyname') FrameWork.Separator(m) closeitem = FrameWork.MenuItem(m, "Close", "W", 'close') *************** *** 208,211 **** --- 209,228 ---- def domenu_open(self, *args): filename = EasyDialogs.AskFileForOpen(typeList=("TEXT",)) + if filename: + self.openscript(filename) + + def domenu_openbyname(self, *args): + # Open a file by name. If the clipboard contains a filename + # use that as the default. + from Carbon import Scrap + try: + sc = Scrap.GetCurrentScrap() + dft = sc.GetScrapFlavorData("TEXT") + except Scrap.Error: + dft = "" + else: + if not os.path.exists(dft): + dft = "" + filename = EasyDialogs.AskString("Open File Named:", default=dft, ok="Open") if filename: self.openscript(filename) From jackjansen@users.sourceforge.net Wed Feb 5 15:49:22 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Feb 2003 07:49:22 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac ic.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv31640 Modified Files: ic.py Log Message: Getting rid of macfs and FSSpecs. Index: ic.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/ic.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ic.py 30 Dec 2002 22:04:20 -0000 1.1 --- ic.py 5 Feb 2003 15:49:19 -0000 1.2 *************** *** 4,8 **** --- 4,10 ---- import string import sys + import os from Carbon import Res + import Carbon.File import macfs import macostools *************** *** 217,227 **** def settypecreator(self, file): ! if type(file) == type(''): ! fss = macfs.FSSpec(file) ! else: ! fss = file ! name = fss.as_tuple()[2] ! record = self.mapfile(name) ! fss.SetCreatorType(record[2], record[1]) macostools.touched(fss) --- 219,225 ---- def settypecreator(self, file): ! file = Carbon.File.pathname(file) ! record = self.mapfile(os.path.split(file)[1]) ! MacOS.SetCreatorAndType(file, record[2], record[1]) macostools.touched(fss) From jackjansen@users.sourceforge.net Wed Feb 5 15:44:06 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Feb 2003 07:44:06 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac cfmfile.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv29618 Modified Files: cfmfile.py Log Message: Got rid of macfs Index: cfmfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/cfmfile.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** cfmfile.py 30 Dec 2002 22:04:20 -0000 1.1 --- cfmfile.py 5 Feb 2003 15:44:03 -0000 1.2 *************** *** 6,10 **** __author__ = "jvr" ! import macfs import struct from Carbon import Res --- 6,10 ---- __author__ = "jvr" ! import Carbon.File import struct from Carbon import Res *************** *** 29,36 **** srclist = list(srclist) for i in range(len(srclist)): ! if type(srclist[i]) == macfs.FSSpecType: ! srclist[i] = srclist[i].as_pathname() ! if type(dst) == macfs.FSSpecType: ! dst = dst.as_pathname() dstfile = open(dst, "wb") --- 29,34 ---- srclist = list(srclist) for i in range(len(srclist)): ! srclist[i] = Carbon.File.pathname(srclist[i]) ! dst = Carbon.File.pathname(dst) dstfile = open(dst, "wb") From jlt63@users.sourceforge.net Wed Feb 5 16:46:04 2003 From: jlt63@users.sourceforge.net (jlt63@users.sourceforge.net) Date: Wed, 05 Feb 2003 08:46:04 -0800 Subject: [Python-checkins] python/dist/src/Lib/test regrtest.py,1.122,1.123 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv23501 Modified Files: regrtest.py Log Message: Patch #551977: Regression exceptions for cygwin Applied the skip test_ossaudiodev patch. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.122 retrieving revision 1.123 diff -C2 -d -r1.122 -r1.123 *** regrtest.py 3 Feb 2003 15:19:27 -0000 1.122 --- regrtest.py 5 Feb 2003 16:46:01 -0000 1.123 *************** *** 869,872 **** --- 869,873 ---- test_mpz test_nis + test_ossaudiodev test_socketserver test_sunaudiodev From tim_one@users.sourceforge.net Wed Feb 5 18:29:35 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 05 Feb 2003 10:29:35 -0800 Subject: [Python-checkins] python/dist/src/Lib repr.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv15673/Lib Modified Files: repr.py Log Message: [680789] Debug with long array takes forever Added array.array to the types repr.py knows about, after a suggestion from Jurjen N.E. Bos. Index: repr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/repr.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** repr.py 29 Oct 2001 22:25:44 -0000 1.14 --- repr.py 5 Feb 2003 18:29:33 -0000 1.15 *************** *** 8,11 **** --- 8,12 ---- self.maxtuple = 6 self.maxlist = 6 + self.maxarray = 5 self.maxdict = 4 self.maxstring = 30 *************** *** 49,52 **** --- 50,70 ---- if n > self.maxlist: s = s + ', ...' return '[' + s + ']' + + def repr_array(self, x, level): + n = len(x) + header = "array('%s', [" % x.typecode + if n == 0: + return header + "])" + if level <= 0: + return header + "...])" + s = '' + for i in range(min(n, self.maxarray)): + if s: + s += ', ' + s += self.repr1(x[i], level-1) + if n > self.maxarray: + s += ', ...' + return header + s + "])" + def repr_dict(self, x, level): n = len(x) From tim_one@users.sourceforge.net Wed Feb 5 18:29:36 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 05 Feb 2003 10:29:36 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_repr.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv15673/Lib/test Modified Files: test_repr.py Log Message: [680789] Debug with long array takes forever Added array.array to the types repr.py knows about, after a suggestion from Jurjen N.E. Bos. Index: test_repr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_repr.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** test_repr.py 16 Jan 2003 04:56:52 -0000 1.15 --- test_repr.py 5 Feb 2003 18:29:33 -0000 1.16 *************** *** 35,38 **** --- 35,40 ---- def test_container(self): + from array import array + eq = self.assertEquals # Tuples give up after 6 elements *************** *** 56,59 **** --- 58,71 ---- d['arthur'] = 1 eq(r(d), "{'alice': 1, 'arthur': 1, 'bob': 2, 'charles': 3, ...}") + + # array.array after 5. + eq(r(array('i')), "array('i', [])") + eq(r(array('i', [1])), "array('i', [1])") + eq(r(array('i', [1, 2])), "array('i', [1, 2])") + eq(r(array('i', [1, 2, 3])), "array('i', [1, 2, 3])") + eq(r(array('i', [1, 2, 3, 4])), "array('i', [1, 2, 3, 4])") + eq(r(array('i', [1, 2, 3, 4, 5])), "array('i', [1, 2, 3, 4, 5])") + eq(r(array('i', [1, 2, 3, 4, 5, 6])), + "array('i', [1, 2, 3, 4, 5, ...])") def test_numbers(self): From tim_one@users.sourceforge.net Wed Feb 5 18:29:37 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 05 Feb 2003 10:29:37 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.641,1.642 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv15673/Misc Modified Files: NEWS Log Message: [680789] Debug with long array takes forever Added array.array to the types repr.py knows about, after a suggestion from Jurjen N.E. Bos. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.641 retrieving revision 1.642 diff -C2 -d -r1.641 -r1.642 *** NEWS 4 Feb 2003 20:59:40 -0000 1.641 --- NEWS 5 Feb 2003 18:29:34 -0000 1.642 *************** *** 146,149 **** --- 146,152 ---- ------- + - array.array was added to the types repr.py knows about (see + ). + - The new pickletools.py contains lots of documentation about pickle internals, and supplies some helpers for working with pickles, such as From akuchling@users.sourceforge.net Wed Feb 5 20:21:53 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Wed, 05 Feb 2003 12:21:53 -0800 Subject: [Python-checkins] python/nondist/peps pep-0042.txt,1.66,1.67 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv26032 Modified Files: pep-0042.txt Log Message: Add a wish Index: pep-0042.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0042.txt,v retrieving revision 1.66 retrieving revision 1.67 diff -C2 -d -r1.66 -r1.67 *** pep-0042.txt 31 Jan 2003 00:18:59 -0000 1.66 --- pep-0042.txt 5 Feb 2003 20:21:49 -0000 1.67 *************** *** 237,240 **** --- 237,245 ---- http://www.python.org/sf/415694 + - pydoc should be integrated with the HTML docs, or at least + be able to link to them. + + http://www.python.org/sf/405554 + C API wishes From tim_one@users.sourceforge.net Wed Feb 5 19:55:56 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 05 Feb 2003 11:55:56 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv13931/Lib Modified Files: pickletools.py Log Message: dis(): Added an optional memo argument, so that multiple pickles in a file can be dumped without (bogus) complaint if the the pickles were created using a single pickle memo. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** pickletools.py 31 Jan 2003 16:43:39 -0000 1.25 --- pickletools.py 5 Feb 2003 19:55:53 -0000 1.26 *************** *** 1862,1866 **** # A symbolic pickle disassembler. ! def dis(pickle, out=None, indentlevel=4): """Produce a symbolic disassembly of a pickle. --- 1862,1866 ---- # A symbolic pickle disassembler. ! def dis(pickle, out=None, memo=None, indentlevel=4): """Produce a symbolic disassembly of a pickle. *************** *** 1872,1875 **** --- 1872,1881 ---- printed. It defaults to sys.stdout. + Optional arg 'memo' is a Python dict, used as the pickle's memo. It + may be mutated by dis(), if the pickle contains PUT or BINPUT opcodes. + Passing the same memo object to another dis() call then allows disassembly + to proceed across multiple pickles that were all created by the same + pickler with the same memo. Ordinarily you don't need to worry about this. + Optional arg indentlevel is the number of blanks by which to indent a new MARK level. It defaults to 4. *************** *** 1896,1900 **** stack = [] # crude emulation of unpickler stack ! memo = {} # crude emulation of unpicker memo maxproto = -1 # max protocol number seen markstack = [] # bytecode positions of MARK opcodes --- 1902,1907 ---- stack = [] # crude emulation of unpickler stack ! if memo is None: ! memo = {} # crude emulation of unpicker memo maxproto = -1 # max protocol number seen markstack = [] # bytecode positions of MARK opcodes *************** *** 2196,2200 **** --- 2203,2236 ---- """ + _memo_test = r""" + >>> import pickle + >>> from StringIO import StringIO + >>> f = StringIO() + >>> p = pickle.Pickler(f, 2) + >>> x = [1, 2, 3] + >>> p.dump(x) + >>> p.dump(x) + >>> f.seek(0) + >>> memo = {} + >>> dis(f, memo=memo) + 0: \x80 PROTO 2 + 2: ] EMPTY_LIST + 3: q BINPUT 0 + 5: ( MARK + 6: K BININT1 1 + 8: K BININT1 2 + 10: K BININT1 3 + 12: e APPENDS (MARK at 5) + 13: . STOP + highest protocol among opcodes = 2 + >>> dis(f, memo=memo) + 14: \x80 PROTO 2 + 16: h BINGET 0 + 18: . STOP + highest protocol among opcodes = 2 + """ + __test__ = {'disassembler_test': _dis_test, + 'disassembler_memo_test': _memo_test, } From tim_one@users.sourceforge.net Wed Feb 5 19:35:22 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 05 Feb 2003 11:35:22 -0800 Subject: [Python-checkins] python/dist/src/Objects object.c,2.196,2.197 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv3511/python/Objects Modified Files: object.c Log Message: SF bug 681122: Built-in function dir() causes refcount leak in baseclasses. merge_class_dict(): This was missing a decref. Bugfix candidate. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.196 retrieving revision 2.197 diff -C2 -d -r2.196 -r2.197 *** object.c 20 Jan 2003 16:54:59 -0000 2.196 --- object.c 5 Feb 2003 19:35:19 -0000 2.197 *************** *** 1657,1660 **** --- 1657,1661 ---- else { for (i = 0; i < n; i++) { + int status; PyObject *base = PySequence_GetItem(bases, i); if (base == NULL) { *************** *** 1662,1666 **** return -1; } ! if (merge_class_dict(dict, base) < 0) { Py_DECREF(bases); return -1; --- 1663,1669 ---- return -1; } ! status = merge_class_dict(dict, base); ! Py_DECREF(base); ! if (status < 0) { Py_DECREF(bases); return -1; From akuchling@users.sourceforge.net Wed Feb 5 21:15:44 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Wed, 05 Feb 2003 13:15:44 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.42,1.43 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv18866 Modified Files: libdatetime.tex Log Message: Markup fixes; in particular, the tables are now reasonable width Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** libdatetime.tex 30 Jan 2003 01:03:38 -0000 1.42 --- libdatetime.tex 5 Feb 2003 21:15:38 -0000 1.43 *************** *** 35,41 **** name, and whether Daylight Saving Time is in effect. Note that no concrete \class{tzinfo} classes are supplied by the \module{datetime} ! module. Instead, they provide a framework for incorporating the level ! of detail an application may require. The rules for time adjustment across ! the world are more political than rational, and there is no standard suitable for every application. --- 35,41 ---- name, and whether Daylight Saving Time is in effect. Note that no concrete \class{tzinfo} classes are supplied by the \module{datetime} ! module. Supporting timezones at whatever level of detail is required ! is up to the application. The rules for time adjustment across the ! world are more political than rational, and there is no standard suitable for every application. *************** *** 202,237 **** % XXX this table is too wide! ! \begin{tableiii}{c|l|c}{code}{Operation}{Result}{Notes} ! \lineiii{\var{t1} = \var{t2} + \var{t3}} {Sum of \var{t2} and \var{t3}. Afterwards \var{t1}-\var{t2} == \var{t3} and \var{t1}-\var{t3} ! == \var{t2} are true.} ! {(1)} ! \lineiii{\var{t1} = \var{t2} - \var{t3}} ! {Difference of \var{t2} and \var{t3}. Afterwards \var{t1} == ! \var{t2} - \var{t3} and \var{t2} == \var{t1} + \var{t3} are ! true.} ! {(1)} ! \lineiii{\var{t1} = \var{t2} * \var{i} or \var{t1} = \var{i} * \var{t2}} {Delta multiplied by an integer or long. Afterwards \var{t1} // i == \var{t2} is true, ! provided \code{i != 0}. ! In general, \var{t1} * i == \var{t1} * (i-1) + \var{t1} is true.} ! {(1)} ! \lineiii{\var{t1} = \var{t2} // \var{i}} ! {The floor is computed and the remainder (if any) is thrown away.} ! {(3)} ! \lineiii{+\var{t1}} ! {Returns a \class{timedelta} object with the same value.} ! {(2)} ! \lineiii{-\var{t1}} {equivalent to \class{timedelta}(-\var{t1.days}, -\var{t1.seconds}, ! -\var{t1.microseconds}), and to \var{t1}* -1.} ! {(1)(4)} ! \lineiii{abs(\var{t})} {equivalent to +\var{t} when \code{t.days >= 0}, and to ! -\var{t} when \code{t.days < 0}.} ! {(2)} ! \end{tableiii} \noindent Notes: --- 202,237 ---- % XXX this table is too wide! ! \begin{tableii}{c|l}{code}{Operation}{Result} ! \lineii{\var{t1} = \var{t2} + \var{t3}} {Sum of \var{t2} and \var{t3}. Afterwards \var{t1}-\var{t2} == \var{t3} and \var{t1}-\var{t3} ! == \var{t2} are true. ! (1)} ! \lineii{\var{t1} = \var{t2} - \var{t3}} ! {Difference of \var{t2} and \var{t3}. ! Afterwards \var{t1} == \var{t2} - \var{t3} and \var{t2} == \var{t1} + \var{t3} are ! true. ! (1)} ! \lineii{\var{t1} = \var{t2} * \var{i} or \var{t1} = \var{i} * \var{t2}} {Delta multiplied by an integer or long. Afterwards \var{t1} // i == \var{t2} is true, ! provided \code{i != 0}.} ! \lineii{}{In general, \var{t1} * i == \var{t1} * (i-1) + \var{t1} is true. ! (1)} ! \lineii{\var{t1} = \var{t2} // \var{i}} ! {The floor is computed and the remainder (if any) is thrown away. ! (3)} ! \lineii{+\var{t1}} ! {Returns a \class{timedelta} object with the same value. ! (2)} ! \lineii{-\var{t1}} {equivalent to \class{timedelta}(-\var{t1.days}, -\var{t1.seconds}, ! -\var{t1.microseconds}), and to \var{t1}* -1. ! (1)(4)} ! \lineii{abs(\var{t})} {equivalent to +\var{t} when \code{t.days >= 0}, and to ! -\var{t} when \code{t.days < 0}. ! (2)} ! \end{tableii} \noindent Notes: *************** *** 349,402 **** % XXX rewrite to be a table ! \begin{itemize} ! \item ! date1 + timedelta -> date2 - timedelta + date1 -> date2 ! date2 is timedelta.days days removed from the date1, moving forward ! in time if timedelta.days > 0, or backward if timedetla.days < 0. ! date2 - date1 == timedelta.days after. timedelta.seconds and ! timedelta.microseconds are ignored. \exception{OverflowError} is ! raised if date2.year would be smaller than \constant{MINYEAR} or ! larger than \constant{MAXYEAR}. ! \item ! date1 - timedelta -> date2 ! Computes the date2 such that date2 + timedelta == date1. This ! isn't quite equivalent to date1 + (-timedelta), because -timedelta ! in isolation can overflow in cases where date1 - timedelta does ! not. timedelta.seconds and timedelta.microseconds are ignored. ! \item ! date1 - date2 -> timedelta ! This is exact, and cannot overflow. timedelta.seconds and timedelta.microseconds are 0, and date2 + timedelta == date1 after. ! \item ! comparison of date to date, where date1 is considered less than ! date2 when date1 precedes date2 in time. In other words, ! date1 < date2 if and only if date1.toordinal() < date2.toordinal(). ! \note{In order to stop comparison from falling back to the default ! scheme of comparing object addresses, date comparison ! normally raises \exception{TypeError} if the other comparand ! isn't also a \class{date} object. However, \code{NotImplemented} ! is returned instead if the other comparand has a ! \method{timetuple} attribute. This hook gives other kinds of ! date objects a chance at implementing mixed-type comparison.} ! ! \item ! hash, use as dict key - \item - efficient pickling ! \item ! in Boolean contexts, all \class{date} objects are considered to be true ! \end{itemize} Instance methods: --- 349,412 ---- % XXX rewrite to be a table ! \begin{tableii}{c|l}{code}{Operation}{Result} ! \lineii{\var{date2} = \var{date1} + \var{timedelta}} ! {\var{date2} is \code{\var{timedelta}.days} days removed from ! \var{date1}. (1)} ! \lineii{\var{date2} = \var{date1} - \var{timedelta}} ! {Computes \var{date2} such that \code{\var{date2} + \var{timedelta} ! == \var{date1}}. (2)} ! \lineii{\var{timedelta} = \var{date1} - \var{date2}} ! {(3)} ! \lineii{\var{date1}<\var{date2}} ! {\var{date1} is considered less than \var{date2} when \var{date1} ! precedes \var{date2} in time. (4)} ! \end{tableii} ! Notes: ! \begin{description} ! ! \item[(1)] ! \var{date2} is moved forward in time if \code{\var{timedelta}.days ! > 0}, or backward if \code{\var{timedelta}.days < 0}. Afterward ! \code{\var{date2} - \var{date1} == \var{timedelta}.days}. ! \code{\var{timedelta}.seconds} and ! \code{\var{timedelta}.microseconds} are ignored. ! \exception{OverflowError} is raised if \code{\var{date2}.year} ! would be smaller than \constant{MINYEAR} or larger than ! \constant{MAXYEAR}. ! ! \item[(2)] ! This isn't quite equivalent to date1 + ! (-timedelta), because -timedelta in isolation can overflow in cases ! where date1 - timedelta does not. \code{\var{timedelta}.seconds} ! and \code{\var{timedelta}.microseconds} are ignored. ! ! \item[(3)] ! This is exact, and cannot overflow. timedelta.seconds and timedelta.microseconds are 0, and date2 + timedelta == date1 after. ! \item[(4)] ! In other words, \code{date1 < date2} ! if and only if \code{\var{date1}.toordinal() < ! \var{date2}.toordinal()}. ! In order to stop comparison from falling back to the default ! scheme of comparing object addresses, date comparison ! normally raises \exception{TypeError} if the other comparand ! isn't also a \class{date} object. However, \code{NotImplemented} ! is returned instead if the other comparand has a ! \method{timetuple} attribute. This hook gives other kinds of ! date objects a chance at implementing mixed-type comparison. ! \end{description} ! Dates can be used as dictionary keys. In Boolean contexts, all ! \class{date} objects are considered to be true. Instance methods: *************** *** 415,422 **** \code{\var{d}.timetuple()} is equivalent to \code{(\var{d}.year, \var{d}.month, \var{d}.day, ! 0, 0, 0, \# h, m, s ! \var{d}.weekday(), \# 0 is Monday \var{d}.toordinal() - date(\var{d}.year, 1, 1).toordinal() + 1, - \# day of year -1)} \end{methoddesc} --- 425,431 ---- \code{\var{d}.timetuple()} is equivalent to \code{(\var{d}.year, \var{d}.month, \var{d}.day, ! 0, 0, 0, ! \var{d}.weekday(), \var{d}.toordinal() - date(\var{d}.year, 1, 1).toordinal() + 1, -1)} \end{methoddesc} *************** *** 430,434 **** \begin{methoddesc}{weekday}{} Return the day of the week as an integer, where Monday is 0 and ! Sunday is 6. For example, date(2002, 12, 4).weekday() == 2, a Wednesday. See also \method{isoweekday()}. --- 439,443 ---- \begin{methoddesc}{weekday}{} Return the day of the week as an integer, where Monday is 0 and ! Sunday is 6. For example, \code{date(2002, 12, 4).weekday() == 2}, a Wednesday. See also \method{isoweekday()}. *************** *** 437,441 **** \begin{methoddesc}{isoweekday}{} Return the day of the week as an integer, where Monday is 1 and ! Sunday is 7. For example, date(2002, 12, 4).isoweekday() == 3, a Wednesday. See also \method{weekday()}, \method{isocalendar()}. --- 446,450 ---- \begin{methoddesc}{isoweekday}{} Return the day of the week as an integer, where Monday is 1 and ! Sunday is 7. For example, \code{date(2002, 12, 4).isoweekday() == 3}, a Wednesday. See also \method{weekday()}, \method{isocalendar()}. *************** *** 458,464 **** year 2004 begins on Monday, 29 Dec 2003 and ends on Sunday, 4 Jan 2004, so that ! ! date(2003, 12, 29).isocalendar() == (2004, 1, 1) ! date(2004, 1, 4).isocalendar() == (2004, 1, 7) \end{methoddesc} --- 467,473 ---- year 2004 begins on Monday, 29 Dec 2003 and ends on Sunday, 4 Jan 2004, so that ! \code{date(2003, 12, 29).isocalendar() == (2004, 1, 1)} ! and ! \code{date(2004, 1, 4).isocalendar() == (2004, 1, 7)}. \end{methoddesc} *************** *** 466,470 **** Return a string representing the date in ISO 8601 format, 'YYYY-MM-DD'. For example, ! date(2002, 12, 4).isoformat() == '2002-12-04'. \end{methoddesc} --- 475,479 ---- Return a string representing the date in ISO 8601 format, 'YYYY-MM-DD'. For example, ! \code{date(2002, 12, 4).isoformat() == '2002-12-04'}. \end{methoddesc} *************** *** 591,596 **** Return the \class{datetime} corresponding to the proleptic Gregorian ordinal, where January 1 of year 1 has ordinal 1. ! \exception{ValueError} is raised unless 1 <= ordinal <= ! datetime.max.toordinal(). The hour, minute, second and microsecond of the result are all 0, and \member{tzinfo} is \code{None}. --- 600,605 ---- Return the \class{datetime} corresponding to the proleptic Gregorian ordinal, where January 1 of year 1 has ordinal 1. ! \exception{ValueError} is raised unless \code{1 <= ordinal <= ! datetime.max.toordinal()}. The hour, minute, second and microsecond of the result are all 0, and \member{tzinfo} is \code{None}. *************** *** 662,674 **** Supported operations: ! \begin{itemize} ! \item ! datetime1 + timedelta -> datetime2 ! timedelta + datetime1 -> datetime2 datetime2 is a duration of timedelta removed from datetime1, moving ! forward in time if timedelta.days > 0, or backward if ! timedelta.days < 0. The result has the same \member{tzinfo} member as the input datetime, and datetime2 - datetime1 == timedelta after. \exception{OverflowError} is raised if datetime2.year would be --- 671,694 ---- Supported operations: ! \begin{tableii}{c|l}{code}{Operation}{Result} ! \lineii{\var{datetime2} = \var{datetime1} + \var{timedelta}}{(1)} ! \lineii{\var{datetime2} = \var{datetime1} - \var{timedelta}}{(2)} ! ! \lineii{\var{timedelta} = \var{datetime1} - \var{datetime2}}{(3)} ! ! \lineii{\var{datetime1} < \var{datetime2}} ! {Compares \class{datetime} to \class{datetime}. ! (4)} ! ! \end{tableii} ! ! \begin{description} ! ! \item[(1)] datetime2 is a duration of timedelta removed from datetime1, moving ! forward in time if \code{\var{timedelta}.days} > 0, or backward if ! \code{\var{timedelta}.days} < 0. The result has the same \member{tzinfo} member as the input datetime, and datetime2 - datetime1 == timedelta after. \exception{OverflowError} is raised if datetime2.year would be *************** *** 677,683 **** aware object. ! \item ! datetime1 - timedelta -> datetime2 ! Computes the datetime2 such that datetime2 + timedelta == datetime1. As for addition, the result has the same \member{tzinfo} member --- 697,701 ---- aware object. ! \item[(2)] Computes the datetime2 such that datetime2 + timedelta == datetime1. As for addition, the result has the same \member{tzinfo} member *************** *** 688,694 **** datetime1 - timedelta does not. ! \item ! datetime1 - datetime2 -> timedelta ! Subtraction of a \class{datetime} from a \class{datetime} is defined only if both --- 706,710 ---- datetime1 - timedelta does not. ! \item[(3)] Subtraction of a \class{datetime} from a \class{datetime} is defined only if both *************** *** 709,717 **** except that the implementation never overflows. ! \item ! comparison of \class{datetime} to \class{datetime}, ! where \var{a} is considered less than \var{b} ! when \var{a} precedes \var{b} in time. If one comparand is naive and ! the other is aware, \exception{TypeError} is raised. If both comparands are aware, and have the same \member{tzinfo} member, the common \member{tzinfo} member is ignored and the base datetimes --- 725,735 ---- except that the implementation never overflows. ! \item[(4)] ! ! \var{datetime1} is considered less than \var{datetime2} ! when \var{datetime1} precedes \var{datetime2} in time. ! ! If one comparand is naive and ! the other is aware, \exception{TypeError} is raised. If both comparands are aware, and have the same \member{tzinfo} member, the common \member{tzinfo} member is ignored and the base datetimes *************** *** 728,741 **** comparison.} ! \item ! hash, use as dict key ! \item ! efficient pickling - \item - in Boolean contexts, all \class{datetime} objects are considered - to be true - \end{itemize} Instance methods: --- 746,754 ---- comparison.} ! \end{description} ! \class{datetime} objects can be used as dictionary keys. In Boolean ! contexts, all \class{datetime} objects are considered to be true. Instance methods: *************** *** 774,778 **** \code{None}). ! If code{\var{self}.tzinfo} is \var{tz}, \code{\var{self}.astimezone(\var{tz})} is equal to \var{self}: no adjustment of date or time members is performed. --- 787,791 ---- \code{None}). ! If \code{\var{self}.tzinfo} is \var{tz}, \code{\var{self}.astimezone(\var{tz})} is equal to \var{self}: no adjustment of date or time members is performed. From akuchling@users.sourceforge.net Wed Feb 5 21:35:12 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Wed, 05 Feb 2003 13:35:12 -0800 Subject: [Python-checkins] python/dist/src/Lib gzip.py,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv25917 Modified Files: gzip.py Log Message: [Patch #654421 from Matthew Mueller] gzip shouldn't raise ValueError on corrupt files Currently the gzip module will raise a ValueError if the file was corrupt (bad crc or bad size). I can't see how that applies to reading a corrupt file. IOError seems better, and it's what code will likely be looking for. Index: gzip.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/gzip.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** gzip.py 5 Nov 2002 20:38:54 -0000 1.37 --- gzip.py 5 Feb 2003 21:35:07 -0000 1.38 *************** *** 306,312 **** isize = U32(read32(self.fileobj)) # may exceed 2GB if U32(crc32) != U32(self.crc): ! raise ValueError, "CRC check failed" elif isize != LOWU32(self.size): ! raise ValueError, "Incorrect length of data produced" def close(self): --- 306,312 ---- isize = U32(read32(self.fileobj)) # may exceed 2GB if U32(crc32) != U32(self.crc): ! raise IOError, "CRC check failed" elif isize != LOWU32(self.size): ! raise IOError, "Incorrect length of data produced" def close(self): From tim_one@users.sourceforge.net Wed Feb 5 22:29:04 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 05 Feb 2003 14:29:04 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime test_datetime.py,1.110,1.111 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv16957 Modified Files: test_datetime.py Log Message: Bring the pickle tests into synch w/ 2.3 CVS. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.110 retrieving revision 1.111 diff -C2 -d -r1.110 -r1.111 *** test_datetime.py 1 Feb 2003 03:02:34 -0000 1.110 --- test_datetime.py 5 Feb 2003 22:29:00 -0000 1.111 *************** *** 15,33 **** from datetime import date, datetime ! ! pickle_choices = [ ! (pickle, pickle, 0), ! (pickle, pickle, 1), ! (pickle, pickle, 2), ! (cPickle, cPickle, 0), ! (cPickle, cPickle, 1), ! ## (cPickle, cPickle, 2), ! (pickle, cPickle, 0), ! (pickle, cPickle, 1), ! ## (pickle, cPickle, 2), ! (cPickle, pickle, 0), ! (cPickle, pickle, 1), ! ## (cPickle, pickle, 2), ! ] --- 15,24 ---- from datetime import date, datetime ! # Before Python 2.3, proto=2 was taken as a synonym for proto=1. ! pickle_choices = [(pickler, unpickler, proto) ! for pickler in pickle, cPickle ! for unpickler in pickle, cPickle ! for proto in range(3)] ! assert len(pickle_choices) == 2*2*3 From andrewmcnamara@users.sourceforge.net Wed Feb 5 22:30:45 2003 From: andrewmcnamara@users.sourceforge.net (andrewmcnamara@users.sourceforge.net) Date: Wed, 05 Feb 2003 14:30:45 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv17473/test Modified Files: test_csv.py Log Message: Remove a bunch of tests that were no longer relevant after quoting/quotechar were rationalised. Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** test_csv.py 5 Feb 2003 03:21:39 -0000 1.17 --- test_csv.py 5 Feb 2003 22:30:42 -0000 1.18 *************** *** 32,41 **** self.assertEqual(parser.quotechar, "'") - parser = _csv.parser(quoting = csv.QUOTE_NONE) - self.assertEqual(parser.quotechar, None) - - parser = _csv.parser(quotechar=None,quoting=csv.QUOTE_ALL) - self.assertEqual(parser.quoting, csv.QUOTE_NONE) - def test_attr_validation(self): parser = _csv.parser() --- 32,35 ---- *************** *** 46,51 **** self.assertRaises(TypeError, setattr, parser, 'quotechar', 0) self.assertRaises(TypeError, setattr, parser, 'escapechar', 0) - parser.quotechar=None - self.assertRaises(TypeError, setattr, parser, 'quoting', 1) self.assertRaises(TypeError, setattr, parser, 'lineterminator', None) --- 40,43 ---- *************** *** 59,66 **** self.assertEqual(parser.quotechar, "'") - parser = _csv.parser() - parser.quoting = csv.QUOTE_NONE - self.assertEqual(parser.quotechar, None) - def test_join_bigfield(self): # This exercises the buffer realloc functionality --- 51,54 ---- *************** *** 89,93 **** # FAIL - need to fix # self.assertEqual(parser.join(['a','1','p,"q"']), 'a,1,"p,\\"q"\r\n') ! parser.quotechar = None self.assertEqual(parser.join(['a','1','p,q']), 'a,1,p\\,q\r\n') --- 77,81 ---- # FAIL - need to fix # self.assertEqual(parser.join(['a','1','p,"q"']), 'a,1,"p,\\"q"\r\n') ! parser.quoting = csv.QUOTE_NONE self.assertEqual(parser.join(['a','1','p,q']), 'a,1,p\\,q\r\n') From jhylton@users.sourceforge.net Wed Feb 5 22:39:32 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Wed, 05 Feb 2003 14:39:32 -0800 Subject: [Python-checkins] python/dist/src/Objects frameobject.c,2.72,2.73 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv21960/Objects Modified Files: frameobject.c Log Message: Refactor the logic for setting f_builtins. For the case where the current globals match the previous frame's globals, eliminates three tests in two if statements. For the case where we just get __builtins__ from a module, eliminate a couple of tests. Index: frameobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/frameobject.c,v retrieving revision 2.72 retrieving revision 2.73 diff -C2 -d -r2.72 -r2.73 *** frameobject.c 31 Dec 2002 03:42:13 -0000 2.72 --- frameobject.c 5 Feb 2003 22:39:29 -0000 2.73 *************** *** 555,560 **** if (back == NULL || back->f_globals != globals) { builtins = PyDict_GetItem(globals, builtin_object); ! if (builtins != NULL && PyModule_Check(builtins)) ! builtins = PyModule_GetDict(builtins); } else { --- 555,578 ---- if (back == NULL || back->f_globals != globals) { builtins = PyDict_GetItem(globals, builtin_object); ! if (builtins) { ! if (PyModule_Check(builtins)) { ! builtins = PyModule_GetDict(builtins); ! assert(!builtins || PyDict_Check(builtins)); ! } ! else if (!PyDict_Check(builtins)) ! builtins = NULL; ! } ! if (builtins == NULL) { ! /* No builtins! Make up a minimal one ! Give them 'None', at least. */ ! builtins = PyDict_New(); ! if (builtins == NULL || ! PyDict_SetItemString( ! builtins, "None", Py_None) < 0) ! return NULL; ! } ! else ! Py_INCREF(builtins); ! } else { *************** *** 562,568 **** Save a lookup and a call. */ builtins = back->f_builtins; } - if (builtins != NULL && !PyDict_Check(builtins)) - builtins = NULL; if (free_list == NULL) { f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type, extras); --- 580,586 ---- Save a lookup and a call. */ builtins = back->f_builtins; + assert(builtins != NULL && PyDict_Check(builtins)); + Py_INCREF(builtins); } if (free_list == NULL) { f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type, extras); *************** *** 582,596 **** _Py_NewReference((PyObject *)f); } - if (builtins == NULL) { - /* No builtins! Make up a minimal one. */ - builtins = PyDict_New(); - if (builtins == NULL || /* Give them 'None', at least. */ - PyDict_SetItemString(builtins, "None", Py_None) < 0) { - Py_DECREF(f); - return NULL; - } - } - else - Py_INCREF(builtins); f->f_builtins = builtins; Py_XINCREF(back); --- 600,603 ---- *************** *** 600,612 **** Py_INCREF(globals); f->f_globals = globals; ! if (code->co_flags & CO_NEWLOCALS) { ! if (code->co_flags & CO_OPTIMIZED) ! locals = NULL; /* Let fast_2_locals handle it */ ! else { ! locals = PyDict_New(); ! if (locals == NULL) { ! Py_DECREF(f); ! return NULL; ! } } } --- 607,619 ---- Py_INCREF(globals); f->f_globals = globals; ! /* Most functions have CO_NEWLOCALS and CO_OPTIMIZED set. */ ! if ((code->co_flags & (CO_NEWLOCALS | CO_OPTIMIZED)) == ! (CO_NEWLOCALS | CO_OPTIMIZED)) ! locals = NULL; /* PyFrame_Fast2Locals() will set. */ ! else if (code->co_flags & CO_NEWLOCALS) { ! locals = PyDict_New(); ! if (locals == NULL) { ! Py_DECREF(f); ! return NULL; } } From gvanrossum@users.sourceforge.net Wed Feb 5 22:39:50 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 05 Feb 2003 14:39:50 -0800 Subject: [Python-checkins] python/dist/src/Objects typeobject.c,2.202,2.203 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv22038 Modified Files: typeobject.c Log Message: Fix for SF #668433. I'm not explaining it here; ample comments are in the code. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.202 retrieving revision 2.203 diff -C2 -d -r2.202 -r2.203 *** typeobject.c 7 Jan 2003 13:41:36 -0000 2.202 --- typeobject.c 5 Feb 2003 22:39:45 -0000 2.203 *************** *** 641,646 **** --- 641,649 ---- /* UnTrack and re-Track around the trashcan macro, alas */ + /* See explanation at end of funtion for full disclosure */ PyObject_GC_UnTrack(self); + ++_PyTrash_delete_nesting; Py_TRASHCAN_SAFE_BEGIN(self); + --_PyTrash_delete_nesting; _PyObject_GC_TRACK(self); /* We'll untrack for real later */ *************** *** 690,694 **** --- 693,787 ---- endlabel: + ++_PyTrash_delete_nesting; Py_TRASHCAN_SAFE_END(self); + --_PyTrash_delete_nesting; + + /* Explanation of the weirdness around the trashcan macros: + + Q. What do the trashcan macros do? + + A. Read the comment titled "Trashcan mechanism" in object.h. + For one, this explains why there must be a call to GC-untrack + before the trashcan begin macro. Without understanding the + trashcan code, the answers to the following questions don't make + sense. + + Q. Why do we GC-untrack before the trashcan and then immediately + GC-track again afterward? + + A. In the case that the base class is GC-aware, the base class + probably GC-untracks the object. If it does that using the + UNTRACK macro, this will crash when the object is already + untracked. Because we don't know what the base class does, the + only safe thing is to make sure the object is tracked when we + call the base class dealloc. But... The trashcan begin macro + requires that the object is *untracked* before it is called. So + the dance becomes: + + GC untrack + trashcan begin + GC track + + Q. Why the bizarre (net-zero) manipulation of + _PyTrash_delete_nesting around the trashcan macros? + + A. Some base classes (e.g. list) also use the trashcan mechanism. + The following scenario used to be possible: + + - suppose the trashcan level is one below the trashcan limit + + - subtype_dealloc() is called + + - the trashcan limit is not yet reached, so the trashcan level + is incremented and the code between trashcan begin and end is + executed + + - this destroys much of the object's contents, including its + slots and __dict__ + + - basedealloc() is called; this is really list_dealloc(), or + some other type which also uses the trashcan macros + + - the trashcan limit is now reached, so the object is put on the + trashcan's to-be-deleted-later list + + - basedealloc() returns + + - subtype_dealloc() decrefs the object's type + + - subtype_dealloc() returns + + - later, the trashcan code starts deleting the objects from its + to-be-deleted-later list + + - subtype_dealloc() is called *AGAIN* for the same object + + - at the very least (if the destroyed slots and __dict__ don't + cause problems) the object's type gets decref'ed a second + time, which is *BAD*!!! + + The remedy is to make sure that if the code between trashcan + begin and end in subtype_dealloc() is called, the code between + trashcan begin and end in basedealloc() will also be called. + This is done by decrementing the level after passing into the + trashcan block, and incrementing it just before leaving the + block. + + But now it's possible that a chain of objects consisting solely + of objects whose deallocator is subtype_dealloc() will defeat + the trashcan mechanism completely: the decremented level means + that the effective level never reaches the limit. Therefore, we + *increment* the level *before* entering the trashcan block, and + matchingly decrement it after leaving. This means the trashcan + code will trigger a little early, but that's no big deal. + + Q. Are there any live examples of code in need of all this + complexity? + + A. Yes. See SF bug 668433 for code that crashed (when Python was + compiled in debug mode) before the trashcan level manipulations + were added. For more discussion, see SF patches 581742, 575073 + and bug 574207. + */ } From jackjansen@users.sourceforge.net Wed Feb 5 22:52:18 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Feb 2003 14:52:18 -0800 Subject: [Python-checkins] python/dist/src/Mac/Unsupported unshar.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Unsupported In directory sc8-pr-cvs1:/tmp/cvs-serv26887/Unsupported Added Files: unshar.py Log Message: I don't think this script serves a useful purpose anymore, and I can't be bothered to fix it. --- NEW FILE: unshar.py --- # Extract files from a SHAR archive. # Run this on the Mac. # Usage: # >>> import unshar # >>> f = open('SHAR') # >>> unshar.unshar(f) import string import EasyDialogs def unshar(fp, verbose=0, overwrite=0): ofp = None file = None while 1: line = fp.readline() if verbose > 3: print 'Got:', `line` if line[:1] == 'X': # Most common case first if ofp: ofp.write(line[1:]) continue if not line: if verbose: print 'EOF' if ofp: print 'Unterminated file -- closing' ofp.close() ofp = None break if line[0] == '#': if verbose: print line, continue if line[:14] == 'sed "s/^X//" >': if verbose: print "!!!", `line` i = string.find(line, "'") j = string.find(line, "'", i+1) if i >= 0 and j > i: file = line[i+1:j] if '/' in file: words = string.splitfields(file, '/') for funny in '', '.': while funny in words: words.remove(funny) for i in range(len(words)): if words[i] == '..': words[i] = '' words.insert(0, '') file = string.joinfields(words, ':') try: ofp = open(file, 'r') ofp.close() ofp = None over = 1 except IOError: over = 0 if over and not overwrite: print 'Skipping', file, '(already exists) ...' continue ofp = open(file, 'w') if over: print 'Overwriting', file, '...' else: print 'Writing', file, '...' continue if line == 'END_OF_FILE\n': if not file: print 'Unexpected END_OF_FILE marker' if ofp: print 'done' ofp.close() ofp = None else: print 'done skipping' file = None continue if verbose: print "...", `line` def main(): import sys import os if len(sys.argv) > 1: for fname in sys.argv[1:]: fp = open(fname, 'r') dir, fn = os.path.split(fname) if dir: os.chdir(dir) unshar(fp) else: import macfs fname = EasyDialogs.AskFileForOpen() if not fname: sys.exit(0) fp = open(fname, 'r') dirname = EasyDialogs.AskFolder(message='Folder to save files in:') if not dirname: sys.exit(0) os.chdir(dirname) unshar(fp) if __name__ == '__main__': main() From jackjansen@users.sourceforge.net Wed Feb 5 22:52:18 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Feb 2003 14:52:18 -0800 Subject: [Python-checkins] python/dist/src/Mac/scripts unshar.py,1.3,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv26887/scripts Removed Files: unshar.py Log Message: I don't think this script serves a useful purpose anymore, and I can't be bothered to fix it. --- unshar.py DELETED --- From jackjansen@users.sourceforge.net Wed Feb 5 22:53:31 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Feb 2003 14:53:31 -0800 Subject: [Python-checkins] python/dist/src/Mac/scripts zappycfiles.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv27436 Modified Files: zappycfiles.py Log Message: Removed unused import of macfs. Index: zappycfiles.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/zappycfiles.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** zappycfiles.py 26 Jan 2003 21:40:00 -0000 1.4 --- zappycfiles.py 5 Feb 2003 22:53:29 -0000 1.5 *************** *** 12,16 **** if not sys.argv[1:]: if os.name == 'mac': - import macfs dir = EasyDialogs.AskFolder(message='Directory to zap pyc files in') if not dir: --- 12,15 ---- From jvr@users.sourceforge.net Wed Feb 5 22:59:09 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Wed, 05 Feb 2003 14:59:09 -0800 Subject: [Python-checkins] python/dist/src/Mac/scripts makeclean.py,1.2,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv30078 Removed Files: makeclean.py Log Message: removing old junk --- makeclean.py DELETED --- From jackjansen@users.sourceforge.net Wed Feb 5 23:10:49 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Feb 2003 15:10:49 -0800 Subject: [Python-checkins] python/dist/src/Mac/scripts findgremlins.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv2313 Modified Files: findgremlins.py Log Message: Got rid of macfs and made a bit more OSX-friendly. Index: findgremlins.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/findgremlins.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** findgremlins.py 26 Jan 2003 21:40:00 -0000 1.2 --- findgremlins.py 5 Feb 2003 23:10:46 -0000 1.3 *************** *** 6,10 **** import EasyDialogs ! import macfs import re import os --- 6,10 ---- import EasyDialogs ! import MacOS import re import os *************** *** 21,26 **** walk(path) else: ! cr, tp = macfs.FSSpec(top).GetCreatorType() ! if tp == 'TEXT' and top[-4:] <> ".hqx": data = open(top).read() badcount = 0 --- 21,26 ---- walk(path) else: ! cr, tp = MacOS.GetCreatorAndType(top) ! if tp in ('TEXT', '\0\0\0\0') and top[-4:] <> ".hqx": data = open(top).read() badcount = 0 *************** *** 45,54 **** def main(): ! pathname = EasyDialogs.AskFolder() ! if pathname: ! walk(pathname) if __name__ == '__main__': main() - sys.exit(1) # So we see the output --- 45,57 ---- def main(): ! if sys.argv[1:]: ! for pathname in sys.argv[1:]: ! walk(pathname) ! else: ! pathname = EasyDialogs.AskFolder() ! if pathname: ! walk(pathname) if __name__ == '__main__': main() From jhylton@users.sourceforge.net Wed Feb 5 23:13:29 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Wed, 05 Feb 2003 15:13:29 -0800 Subject: [Python-checkins] python/dist/src/Misc SpecialBuilds.txt,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv3401/Misc Modified Files: SpecialBuilds.txt Log Message: Small function call optimization and special build option for call stats. -DCALL_PROFILE: Count the number of function calls executed. When this symbol is defined, the ceval mainloop and helper functions count the number of function calls made. It keeps detailed statistics about what kind of object was called and whether the call hit any of the special fast paths in the code. Optimization: When we take the fast_function() path, which seems to be taken for most function calls, and there is minimal frame setup to do, avoid call PyEval_EvalCodeEx(). The eval code ex function does a lot of work to handle keywords args and star args, free variables, generators, etc. The inlined version simply allocates the frame and copies the arguments values into the frame. The optimization gets a little help from compile.c which adds a CO_NOFREE flag to code objects that don't have free variables or cell variables. This change allows fast_function() to get into the fast path with fewer tests. I measure a couple of percent speedup in pystone with this change, but there's surely more that can be done. Index: SpecialBuilds.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/SpecialBuilds.txt,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** SpecialBuilds.txt 30 Jul 2002 15:25:57 -0000 1.12 --- SpecialBuilds.txt 5 Feb 2003 23:12:57 -0000 1.13 *************** *** 200,201 **** --- 200,211 ---- Not useful very often, but very useful when needed. + + --------------------------------------------------------------------------- + CALL_PROFILE introduced for Python 2.3 + + Count the number of function calls executed. + + When this symbol is defined, the ceval mainloop and helper functions + count the number of function calls made. It keeps detailed statistics + about what kind of object was called and whether the call hit any of + the special fast paths in the code. From jhylton@users.sourceforge.net Wed Feb 5 23:13:29 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Wed, 05 Feb 2003 15:13:29 -0800 Subject: [Python-checkins] python/dist/src/Include ceval.h,2.46,2.47 compile.h,2.39,2.40 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv3401/Include Modified Files: ceval.h compile.h Log Message: Small function call optimization and special build option for call stats. -DCALL_PROFILE: Count the number of function calls executed. When this symbol is defined, the ceval mainloop and helper functions count the number of function calls made. It keeps detailed statistics about what kind of object was called and whether the call hit any of the special fast paths in the code. Optimization: When we take the fast_function() path, which seems to be taken for most function calls, and there is minimal frame setup to do, avoid call PyEval_EvalCodeEx(). The eval code ex function does a lot of work to handle keywords args and star args, free variables, generators, etc. The inlined version simply allocates the frame and copies the arguments values into the frame. The optimization gets a little help from compile.c which adds a CO_NOFREE flag to code objects that don't have free variables or cell variables. This change allows fast_function() to get into the fast path with fewer tests. I measure a couple of percent speedup in pystone with this change, but there's surely more that can be done. Index: ceval.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/ceval.h,v retrieving revision 2.46 retrieving revision 2.47 diff -C2 -d -r2.46 -r2.47 *** ceval.h 3 Sep 2002 20:10:44 -0000 2.46 --- ceval.h 5 Feb 2003 23:12:56 -0000 2.47 *************** *** 49,52 **** --- 49,54 ---- PyAPI_FUNC(char *) PyEval_GetFuncDesc(PyObject *); + PyAPI_FUNC(PyObject *) PyEval_GetCallStats(PyObject *); + /* this used to be handled on a per-thread basis - now just two globals */ PyAPI_DATA(volatile int) _Py_Ticker; Index: compile.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/compile.h,v retrieving revision 2.39 retrieving revision 2.40 diff -C2 -d -r2.39 -r2.40 *** compile.h 11 Dec 2002 14:04:57 -0000 2.39 --- compile.h 5 Feb 2003 23:12:56 -0000 2.40 *************** *** 35,38 **** --- 35,44 ---- #define CO_NESTED 0x0010 #define CO_GENERATOR 0x0020 + /* The CO_NOFREE flag is set if there are no free or cell variables. + This information is redundant, but it allows a single flag test + to determine whether there is any extra work to be done when the + call frame it setup. + */ + #define CO_NOFREE 0x0040 /* XXX Temporary hack. Until generators are a permanent part of the language, we need a way for a code object to record that generators From jhylton@users.sourceforge.net Wed Feb 5 23:13:04 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Wed, 05 Feb 2003 15:13:04 -0800 Subject: [Python-checkins] python/dist/src/Python ceval.c,2.347,2.348 compile.c,2.272,2.273 sysmodule.c,2.112,2.113 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv3401/Python Modified Files: ceval.c compile.c sysmodule.c Log Message: Small function call optimization and special build option for call stats. -DCALL_PROFILE: Count the number of function calls executed. When this symbol is defined, the ceval mainloop and helper functions count the number of function calls made. It keeps detailed statistics about what kind of object was called and whether the call hit any of the special fast paths in the code. Optimization: When we take the fast_function() path, which seems to be taken for most function calls, and there is minimal frame setup to do, avoid call PyEval_EvalCodeEx(). The eval code ex function does a lot of work to handle keywords args and star args, free variables, generators, etc. The inlined version simply allocates the frame and copies the arguments values into the frame. The optimization gets a little help from compile.c which adds a CO_NOFREE flag to code objects that don't have free variables or cell variables. This change allows fast_function() to get into the fast path with fewer tests. I measure a couple of percent speedup in pystone with this change, but there's surely more that can be done. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.347 retrieving revision 2.348 diff -C2 -d -r2.347 -r2.348 *** ceval.c 19 Jan 2003 05:08:13 -0000 2.347 --- ceval.c 5 Feb 2003 23:12:57 -0000 2.348 *************** *** 88,91 **** --- 88,147 ---- #endif + /* Function call profile */ + #ifdef CALL_PROFILE + #define PCALL_NUM 11 + static int pcall[PCALL_NUM]; + + #define PCALL_ALL 0 + #define PCALL_FUNCTION 1 + #define PCALL_FAST_FUNCTION 2 + #define PCALL_FASTER_FUNCTION 3 + #define PCALL_METHOD 4 + #define PCALL_BOUND_METHOD 5 + #define PCALL_CFUNCTION 6 + #define PCALL_TYPE 7 + #define PCALL_GENERATOR 8 + #define PCALL_OTHER 9 + #define PCALL_POP 10 + + /* Notes about the statistics + + PCALL_FAST stats + + FAST_FUNCTION means no argument tuple needs to be created. + FASTER_FUNCTION means that the fast-path frame setup code is used. + + If there is a method call where the call can be optimized by changing + the argument tuple and calling the function directly, it gets recorded + twice. + + As a result, the relationship among the statistics appears to be + PCALL_ALL == PCALL_FUNCTION + PCALL_METHOD - PCALL_BOUND_METHOD + + PCALL_CFUNCTION + PCALL_TYPE + PCALL_GENERATOR + PCALL_OTHER + PCALL_FUNCTION > PCALL_FAST_FUNCTION > PCALL_FASTER_FUNCTION + PCALL_METHOD > PCALL_BOUND_METHOD + */ + + #define PCALL(POS) pcall[POS]++ + + PyObject * + PyEval_GetCallStats(PyObject *self) + { + return Py_BuildValue("iiiiiiiiii", + pcall[0], pcall[1], pcall[2], pcall[3], + pcall[4], pcall[5], pcall[6], pcall[7], + pcall[8], pcall[9]); + } + #else + #define PCALL(O) + + PyObject * + PyEval_GetCallStats(PyObject *self) + { + Py_INCREF(Py_None); + return Py_None; + } + #endif + static PyTypeObject gentype; *************** *** 476,479 **** --- 532,536 ---- PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals) { + /* XXX raise SystemError if globals is NULL */ return PyEval_EvalCodeEx(co, globals, locals, *************** *** 1981,1984 **** --- 2038,2042 ---- case CALL_FUNCTION: + PCALL(PCALL_ALL); x = call_function(&stack_pointer, oparg); PUSH(x); *************** *** 1996,1999 **** --- 2054,2058 ---- int n = na + 2 * nk; PyObject **pfunc, *func; + PCALL(PCALL_ALL); if (flags & CALL_FLAG_VAR) n++; *************** *** 2318,2324 **** } ! f = PyFrame_New(tstate, /*back*/ ! co, /*code*/ ! globals, locals); if (f == NULL) return NULL; --- 2377,2382 ---- } ! assert(globals != NULL); ! f = PyFrame_New(tstate, co, globals, locals); if (f == NULL) return NULL; *************** *** 2521,2524 **** --- 2579,2584 ---- f->f_back = NULL; + PCALL(PCALL_GENERATOR); + /* Create a new generator that owns the ready to run frame * and return that as the value. */ *************** *** 3199,3208 **** PyObject *x, *w; ! /* Always dispatch PyCFunction first, because ! these are presumed to be the most frequent ! callable object. */ if (PyCFunction_Check(func) && nk == 0) { int flags = PyCFunction_GET_FLAGS(func); if (flags & (METH_NOARGS | METH_O)) { PyCFunction meth = PyCFunction_GET_FUNCTION(func); --- 3259,3268 ---- PyObject *x, *w; ! /* Always dispatch PyCFunction first, because these are ! presumed to be the most frequent callable object. */ if (PyCFunction_Check(func) && nk == 0) { int flags = PyCFunction_GET_FLAGS(func); + PCALL(PCALL_CFUNCTION); if (flags & (METH_NOARGS | METH_O)) { PyCFunction meth = PyCFunction_GET_FUNCTION(func); *************** *** 3230,3233 **** --- 3290,3295 ---- /* optimize access to bound methods */ PyObject *self = PyMethod_GET_SELF(func); + PCALL(PCALL_METHOD); + PCALL(PCALL_BOUND_METHOD); Py_INCREF(self); func = PyMethod_GET_FUNCTION(func); *************** *** 3246,3252 **** --- 3308,3316 ---- } + /* What does this do? */ while ((*pp_stack) > pfunc) { w = EXT_POP(*pp_stack); Py_DECREF(w); + PCALL(PCALL_POP); } return x; *************** *** 3255,3258 **** --- 3319,3327 ---- /* The fast_function() function optimize calls for which no argument tuple is necessary; the objects are passed directly from the stack. + For the simplest case -- a function that takes only positional + arguments and is called with only positional arguments -- it + inlines the most primitive frame setup code from + PyEval_EvalCodeEx(), which vastly reduces the checks that must be + done before evaluating the frame. */ *************** *** 3260,3278 **** fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk) { ! PyObject *co = PyFunction_GET_CODE(func); PyObject *globals = PyFunction_GET_GLOBALS(func); PyObject *argdefs = PyFunction_GET_DEFAULTS(func); - PyObject *closure = PyFunction_GET_CLOSURE(func); PyObject **d = NULL; int nd = 0; if (argdefs != NULL) { d = &PyTuple_GET_ITEM(argdefs, 0); nd = ((PyTupleObject *)argdefs)->ob_size; } ! return PyEval_EvalCodeEx((PyCodeObject *)co, globals, ! (PyObject *)NULL, (*pp_stack)-n, na, ! (*pp_stack)-2*nk, nk, d, nd, ! closure); } --- 3329,3380 ---- fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk) { ! PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); PyObject *globals = PyFunction_GET_GLOBALS(func); PyObject *argdefs = PyFunction_GET_DEFAULTS(func); PyObject **d = NULL; int nd = 0; + PCALL(PCALL_FUNCTION); + PCALL(PCALL_FAST_FUNCTION); + if (argdefs == NULL && co->co_argcount == n && + co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { + PyFrameObject *f; + PyObject *retval = NULL; + PyThreadState *tstate = PyThreadState_GET(); + PyObject **fastlocals, **stack; + int i; + + PCALL(PCALL_FASTER_FUNCTION); + assert(globals != NULL); + /* XXX Perhaps we should create a specialized + PyFrame_New() that doesn't take locals, but does + take builtins without sanity checking them. + */ + f = PyFrame_New(tstate, co, globals, NULL); + if (f == NULL) + return NULL; + + fastlocals = f->f_localsplus; + stack = (*pp_stack) - n; + + for (i = 0; i < n; i++) { + Py_INCREF(*stack); + fastlocals[i] = *stack++; + } + retval = eval_frame(f); + assert(tstate != NULL); + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + return retval; + } if (argdefs != NULL) { d = &PyTuple_GET_ITEM(argdefs, 0); nd = ((PyTupleObject *)argdefs)->ob_size; } ! return PyEval_EvalCodeEx(co, globals, ! (PyObject *)NULL, (*pp_stack)-n, na, ! (*pp_stack)-2*nk, nk, d, nd, ! PyFunction_GET_CLOSURE(func)); } *************** *** 3372,3375 **** --- 3474,3491 ---- if (callargs == NULL) goto call_fail; + #ifdef CALL_PROFILE + /* At this point, we have to look at the type of func to + update the call stats properly. Do it here so as to avoid + exposing the call stats machinery outside ceval.c + */ + if (PyFunction_Check(func)) + PCALL(PCALL_FUNCTION); + else if (PyMethod_Check(func)) + PCALL(PCALL_METHOD); + else if (PyType_Check(func)) + PCALL(PCALL_TYPE); + else + PCALL(PCALL_OTHER); + #endif result = PyObject_Call(func, callargs, kwdict); call_fail: *************** *** 3427,3430 **** --- 3543,3560 ---- if (callargs == NULL) goto ext_call_fail; + #ifdef CALL_PROFILE + /* At this point, we have to look at the type of func to + update the call stats properly. Do it here so as to avoid + exposing the call stats machinery outside ceval.c + */ + if (PyFunction_Check(func)) + PCALL(PCALL_FUNCTION); + else if (PyMethod_Check(func)) + PCALL(PCALL_METHOD); + else if (PyType_Check(func)) + PCALL(PCALL_TYPE); + else + PCALL(PCALL_OTHER); + #endif result = PyObject_Call(func, callargs, kwdict); ext_call_fail: Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.272 retrieving revision 2.273 diff -C2 -d -r2.272 -r2.273 *** compile.c 16 Jan 2003 15:39:07 -0000 2.272 --- compile.c 5 Feb 2003 23:13:00 -0000 2.273 *************** *** 386,389 **** --- 386,392 ---- Py_INCREF(lnotab); co->co_lnotab = lnotab; + if (PyTuple_GET_SIZE(freevars) == 0 && + PyTuple_GET_SIZE(cellvars) == 0) + co->co_flags |= CO_NOFREE; } return co; Index: sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.112 retrieving revision 2.113 diff -C2 -d -r2.112 -r2.113 *** sysmodule.c 8 Jan 2003 14:33:48 -0000 2.112 --- sysmodule.c 5 Feb 2003 23:13:00 -0000 2.113 *************** *** 563,566 **** --- 563,588 ---- } + PyDoc_STRVAR(callstats_doc, + "callstats() -> tuple of integers\n\ + \n\ + Return a tuple of function call statistics, if CALL_PROFILE was defined\n\ + when Python was built. Otherwise, return None.\n\ + \n\ + When enabled, this function returns detailed, implementation-specific\n\ + details about the number of function calls executed. The return value is\n\ + a 11-tuple where the entries in the tuple are counts of:\n\ + 0. all function calls\n\ + 1. calls to PyFunction_Type objects\n\ + 2. PyFunction calls that do not create an argument tuple\n\ + 3. PyFunction calls that do not create an argument tuple\n\ + and bypass PyEval_EvalCodeEx()\n\ + 4. PyMethod calls\n\ + 5. PyMethod calls on bound methods\n\ + 6. PyType calls\n\ + 7. PyCFunction calls\n\ + 8. generator calls\n\ + 9. All other calls\n\ + 10. Number of stack pops performed by call_function()" + ); #ifdef Py_TRACE_REFS *************** *** 576,579 **** --- 598,603 ---- static PyMethodDef sys_methods[] = { /* Might as well keep this in alphabetic order */ + {"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS, + callstats_doc}, {"displayhook", sys_displayhook, METH_O, displayhook_doc}, {"exc_info", (PyCFunction)sys_exc_info, METH_NOARGS, exc_info_doc}, *************** *** 581,586 **** {"exit", sys_exit, METH_VARARGS, exit_doc}, #ifdef Py_USING_UNICODE ! {"getdefaultencoding", (PyCFunction)sys_getdefaultencoding, METH_NOARGS, ! getdefaultencoding_doc}, #endif #ifdef HAVE_DLOPEN --- 605,610 ---- {"exit", sys_exit, METH_VARARGS, exit_doc}, #ifdef Py_USING_UNICODE ! {"getdefaultencoding", (PyCFunction)sys_getdefaultencoding, ! METH_NOARGS, getdefaultencoding_doc}, #endif #ifdef HAVE_DLOPEN From montanaro@users.sourceforge.net Thu Feb 6 01:27:34 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 05 Feb 2003 17:27:34 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv18538 Modified Files: test_csv.py Log Message: uncomment the failing test - better left noisy as a reminder ;-) Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** test_csv.py 5 Feb 2003 22:30:42 -0000 1.18 --- test_csv.py 6 Feb 2003 01:27:31 -0000 1.19 *************** *** 75,80 **** self.assertEqual(parser.join(['a','1','p,q']), 'a,1,"p,q"\r\n') parser.doublequote = 0 ! # FAIL - need to fix ! # self.assertEqual(parser.join(['a','1','p,"q"']), 'a,1,"p,\\"q"\r\n') parser.quoting = csv.QUOTE_NONE self.assertEqual(parser.join(['a','1','p,q']), 'a,1,p\\,q\r\n') --- 75,79 ---- self.assertEqual(parser.join(['a','1','p,q']), 'a,1,"p,q"\r\n') parser.doublequote = 0 ! self.assertEqual(parser.join(['a','1','p,"q"']), 'a,1,"p,\\"q"\r\n') parser.quoting = csv.QUOTE_NONE self.assertEqual(parser.join(['a','1','p,q']), 'a,1,p\\,q\r\n') From anthonybaxter@users.sourceforge.net Thu Feb 6 01:45:14 2003 From: anthonybaxter@users.sourceforge.net (anthonybaxter@users.sourceforge.net) Date: Wed, 05 Feb 2003 17:45:14 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libcmd.tex,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv23648/Doc/lib Modified Files: libcmd.tex Log Message: Updated version of [ 558544 ] cmd.py: add instance-specific stdin/out This patch adds stdin, stdout as optional arguments to the cmd.Cmd constructor (defaulting to sys.stdin, sys.stdout), and changes the Cmd methods throughout to use self.stdout.write() and self.stdin.foo for output and input. This allows much greater flexibility for using cmd - for instance, hooking it into a telnet server. Patch for library module and for documentation. Index: libcmd.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcmd.tex,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** libcmd.tex 27 Dec 2001 05:10:18 -0000 1.12 --- libcmd.tex 6 Feb 2003 01:45:11 -0000 1.13 *************** *** 12,16 **** later be wrapped in a more sophisticated interface. ! \begin{classdesc}{Cmd}{\optional{completekey}} A \class{Cmd} instance or subclass instance is a line-oriented interpreter framework. There is no good reason to instantiate --- 12,16 ---- later be wrapped in a more sophisticated interface. ! \begin{classdesc}{Cmd}{\optional{completekey},\optional{stdin},\optional{stdout}} A \class{Cmd} instance or subclass instance is a line-oriented interpreter framework. There is no good reason to instantiate *************** *** 19,26 **** \class{Cmd}'s methods and encapsulate action methods. ! The optional argument is the \refmodule{readline} name of a completion ! key; it defaults to \kbd{Tab}. If \var{completekey} is not \code{None} ! and \module{readline} is available, command completion is done ! automatically. \end{classdesc} --- 19,32 ---- \class{Cmd}'s methods and encapsulate action methods. ! The optional argument \var{completekey} is the \refmodule{readline} name ! of a completion key; it defaults to \kbd{Tab}. If \var{completekey} is ! not \code{None} and \module{readline} is available, command completion ! is done automatically. ! ! The optional arguments \var{stdin} and \var{stdout} specify the ! input and output file objects that the Cmd instance or subclass ! instance will use for input and output. If not specified, they ! will default to \var{sys.stdin} and \var{sys.stdout}. ! \end{classdesc} From anthonybaxter@users.sourceforge.net Thu Feb 6 01:45:13 2003 From: anthonybaxter@users.sourceforge.net (anthonybaxter@users.sourceforge.net) Date: Wed, 05 Feb 2003 17:45:13 -0800 Subject: [Python-checkins] python/dist/src/Lib cmd.py,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv23648/Lib Modified Files: cmd.py Log Message: Updated version of [ 558544 ] cmd.py: add instance-specific stdin/out This patch adds stdin, stdout as optional arguments to the cmd.Cmd constructor (defaulting to sys.stdin, sys.stdout), and changes the Cmd methods throughout to use self.stdout.write() and self.stdin.foo for output and input. This allows much greater flexibility for using cmd - for instance, hooking it into a telnet server. Patch for library module and for documentation. Index: cmd.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/cmd.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** cmd.py 3 Feb 2003 11:04:27 -0000 1.34 --- cmd.py 6 Feb 2003 01:45:10 -0000 1.35 *************** *** 46,50 **** """ ! import string, sys __all__ = ["Cmd"] --- 46,50 ---- """ ! import string __all__ = ["Cmd"] *************** *** 77,89 **** use_rawinput = 1 ! def __init__(self, completekey='tab'): """Instantiate a line-oriented interpreter framework. ! The optional argument is the readline name of a completion key; ! it defaults to the Tab key. If completekey is not None and the ! readline module is available, command completion is done ! automatically. """ self.cmdqueue = [] self.completekey = completekey --- 77,100 ---- use_rawinput = 1 ! def __init__(self, completekey='tab', stdin=None, stdout=None): """Instantiate a line-oriented interpreter framework. ! The optional argument 'completekey' is the readline name of a ! completion key; it defaults to the Tab key. If completekey is ! not None and the readline module is available, command completion ! is done automatically. The optional arguments stdin and stdout ! specify alternate input and output file objects; if not specified, ! sys.stdin and sys.stdout are used. """ + import sys + if stdin is not None: + self.stdin = stdin + else: + self.stdin = sys.stdin + if stdout is not None: + self.stdout = stdout + else: + self.stdout = sys.stdout self.cmdqueue = [] self.completekey = completekey *************** *** 100,104 **** self.intro = intro if self.intro: ! print self.intro stop = None while not stop: --- 111,115 ---- self.intro = intro if self.intro: ! self.stdout.write(str(self.intro)+"\n") stop = None while not stop: *************** *** 112,118 **** line = 'EOF' else: ! sys.stdout.write(self.prompt) ! sys.stdout.flush() ! line = sys.stdin.readline() if not len(line): line = 'EOF' --- 123,129 ---- line = 'EOF' else: ! self.stdout.write(self.prompt) ! self.stdout.flush() ! line = self.stdin.readline() if not len(line): line = 'EOF' *************** *** 216,220 **** """ ! print '*** Unknown syntax:', line def completedefault(self, *ignored): --- 227,231 ---- """ ! self.stdout.write('*** Unknown syntax: %s\n'%line) def completedefault(self, *ignored): *************** *** 285,293 **** doc=getattr(self, 'do_' + arg).__doc__ if doc: ! print doc return except AttributeError: pass ! print self.nohelp % (arg,) return func() --- 296,304 ---- doc=getattr(self, 'do_' + arg).__doc__ if doc: ! self.stdout.write("%s\n"%str(doc)) return except AttributeError: pass ! self.stdout.write("%s\n"%str(self.nohelp % (arg,))) return func() *************** *** 316,320 **** else: cmds_undoc.append(cmd) ! print self.doc_leader self.print_topics(self.doc_header, cmds_doc, 15,80) self.print_topics(self.misc_header, help.keys(),15,80) --- 327,331 ---- else: cmds_undoc.append(cmd) ! self.stdout.write("%s\n"%str(self.doc_leader)) self.print_topics(self.doc_header, cmds_doc, 15,80) self.print_topics(self.misc_header, help.keys(),15,80) *************** *** 323,331 **** def print_topics(self, header, cmds, cmdlen, maxcol): if cmds: ! print header if self.ruler: ! print self.ruler * len(header) self.columnize(cmds, maxcol-1) ! print def columnize(self, list, displaywidth=80): --- 334,342 ---- def print_topics(self, header, cmds, cmdlen, maxcol): if cmds: ! self.stdout.write("%s\n"%str(header)) if self.ruler: ! self.stdout.write("%s\n"%str(self.ruler * len(header))) self.columnize(cmds, maxcol-1) ! self.stdout.write("\n") def columnize(self, list, displaywidth=80): *************** *** 336,340 **** """ if not list: ! print "" return nonstrings = [i for i in range(len(list)) --- 347,351 ---- """ if not list: ! self.stdout.write("\n") return nonstrings = [i for i in range(len(list)) *************** *** 345,349 **** size = len(list) if size == 1: ! print list[0] return # Try every row count from 1 upwards --- 356,360 ---- size = len(list) if size == 1: ! self.stdout.write('%s\n'%str(list[0])) return # Try every row count from 1 upwards *************** *** 383,385 **** for col in range(len(texts)): texts[col] = texts[col].ljust(colwidths[col]) ! print " ".join(texts) --- 394,396 ---- for col in range(len(texts)): texts[col] = texts[col].ljust(colwidths[col]) ! self.stdout.write("%s\n"%str(" ".join(texts))) From montanaro@users.sourceforge.net Thu Feb 6 04:49:31 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 05 Feb 2003 20:49:31 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv29808 Modified Files: csv.py Log Message: add optional fieldnames and restfield params to csv.reader() which allow the reader to return rows as dicts Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** csv.py 5 Feb 2003 02:21:42 -0000 1.22 --- csv.py 6 Feb 2003 04:49:29 -0000 1.23 *************** *** 94,99 **** class reader(_OCcsv): ! def __init__(self, iterobj, dialect = 'excel', **options): self.iterobj = iter(iterobj) _OCcsv.__init__(self, dialect, **options) --- 94,103 ---- class reader(_OCcsv): ! def __init__(self, iterobj, dialect = 'excel', ! fieldnames=None, restfield=None, ! **options): self.iterobj = iter(iterobj) + self.fieldnames = fieldnames + self.restfield = restfield _OCcsv.__init__(self, dialect, **options) *************** *** 105,108 **** --- 109,119 ---- fields = self.parser.parse(self.iterobj.next()) if fields: + if self.fieldnames is not None: + lf = len(self.fieldnames) + result = dict(zip(self.fieldnames, fields)) + if (lf < len(fields) and + self.restfield is not None): + result[self.restfield] = fields[lf:] + return result return fields From montanaro@users.sourceforge.net Thu Feb 6 04:50:12 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 05 Feb 2003 20:50:12 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv libcsv.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv30062 Modified Files: libcsv.tex Log Message: add missing \subsection{} Index: libcsv.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/libcsv.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** libcsv.tex 3 Feb 2003 06:25:30 -0000 1.3 --- libcsv.tex 6 Feb 2003 04:50:10 -0000 1.4 *************** *** 34,37 **** --- 34,39 ---- preprocessing the data returned from a {}\code{cursor.fetch*()} call. + \subsection{Module Contents} + The \module{csv} module defines the following classes. From montanaro@users.sourceforge.net Thu Feb 6 04:51:50 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 05 Feb 2003 20:51:50 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv30597 Modified Files: test_csv.py Log Message: add tests for reader returning dicts Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** test_csv.py 6 Feb 2003 01:27:31 -0000 1.19 --- test_csv.py 6 Feb 2003 04:51:47 -0000 1.20 *************** *** 242,246 **** class TestDictFields(unittest.TestCase): ! def test_simple_dict(self): fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel", --- 242,246 ---- class TestDictFields(unittest.TestCase): ! def test_write_simple_dict(self): fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel", *************** *** 249,256 **** self.assertEqual(fileobj.getvalue(), "10,,abc\r\n") ! def test_no_fields(self): fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") self.assertRaises(csv.Error, writer.writerow, {"f1": 10, "f3": "abc"}) class TestArrayWrites(unittest.TestCase): --- 249,272 ---- self.assertEqual(fileobj.getvalue(), "10,,abc\r\n") ! def test_write_no_fields(self): fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") self.assertRaises(csv.Error, writer.writerow, {"f1": 10, "f3": "abc"}) + + def test_read_dict_fields(self): + reader = csv.reader(StringIO("1,2,abc\r\n"), dialect="excel", + fieldnames=["f1", "f2", "f3"]) + self.assertEqual(reader.next(), {"f1": '1', "f2": '2', "f3": 'abc'}) + + def test_read_short(self): + reader = csv.reader(StringIO("1,2,abc,4,5,6\r\n"), dialect="excel", + fieldnames=["f1", "f2"]) + self.assertEqual(reader.next(), {"f1": '1', "f2": '2'}) + + def test_read_short_with_rest(self): + reader = csv.reader(StringIO("1,2,abc,4,5,6\r\n"), dialect="excel", + fieldnames=["f1", "f2"], restfield="_rest") + self.assertEqual(reader.next(), {"f1": '1', "f2": '2', + "_rest": ["abc", "4", "5", "6"]}) class TestArrayWrites(unittest.TestCase): From nnorwitz@users.sourceforge.net Thu Feb 6 05:02:43 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Wed, 05 Feb 2003 21:02:43 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libcmd.tex,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv1704/lib Modified Files: libcmd.tex Log Message: Provide version changed info Index: libcmd.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcmd.tex,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** libcmd.tex 6 Feb 2003 01:45:11 -0000 1.13 --- libcmd.tex 6 Feb 2003 05:02:39 -0000 1.14 *************** *** 29,32 **** --- 29,33 ---- will default to \var{sys.stdin} and \var{sys.stdout}. + \versionchanged[The \var{stdin} and \var{stdout} parameters were added.]{2.3} \end{classdesc} From akuchling@users.sourceforge.net Thu Feb 6 14:38:50 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Thu, 06 Feb 2003 06:38:50 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libwarnings.tex,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv5176 Modified Files: libwarnings.tex Log Message: Fix description of filterwarnings() parameters (error noted by Richard Jones at http://mechanicalcat.net/cgi-bin/log/python/turning_warnings_off.html) Index: libwarnings.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libwarnings.tex,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** libwarnings.tex 14 Aug 2002 16:40:54 -0000 1.10 --- libwarnings.tex 6 Feb 2003 14:38:45 -0000 1.11 *************** *** 117,128 **** \end{tableii} ! \item \var{message} is a compiled regular expression that the warning ! message must match (the match is case-insensitive) \item \var{category} is a class (a subclass of \exception{Warning}) of which the warning category must be a subclass in order to match ! \item \var{module} is a compiled regular expression that the module ! name must match \item \var{lineno} is an integer that the line number where the --- 117,129 ---- \end{tableii} ! \item \var{message} is a string containing a regular expression that ! the warning message must match (the match is compiled to always be ! case-insensitive) \item \var{category} is a class (a subclass of \exception{Warning}) of which the warning category must be a subclass in order to match ! \item \var{module} is a string containing a regular expression that the module ! name must match (the match is compiled to be case-sensitive) \item \var{lineno} is an integer that the line number where the From akuchling@users.sourceforge.net Thu Feb 6 15:14:08 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Thu, 06 Feb 2003 07:14:08 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.112,1.113 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv24641 Modified Files: whatsnew23.tex Log Message: Mention FutureWarning for large ints Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.112 retrieving revision 1.113 diff -C2 -d -r1.112 -r1.113 *** whatsnew23.tex 3 Feb 2003 15:16:15 -0000 1.112 --- whatsnew23.tex 6 Feb 2003 15:14:04 -0000 1.113 *************** *** 2074,2077 **** --- 2074,2082 ---- exists. + \item Large octal and hex literals such as + 0xffffffff now trigger a \exception{FutureWarning} because currently + they're stored as 32-bit numbers and result in a negative value, but + in Python 2.4 they'll become positive long integers. + \item You can no longer disable assertions by assigning to \code{__debug__}. From akuchling@users.sourceforge.net Thu Feb 6 15:22:52 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Thu, 06 Feb 2003 07:22:52 -0800 Subject: [Python-checkins] python/dist/src/Objects typeobject.c,2.203,2.204 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv29904 Modified Files: typeobject.c Log Message: Comment typo fix Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.203 retrieving revision 2.204 diff -C2 -d -r2.203 -r2.204 *** typeobject.c 5 Feb 2003 22:39:45 -0000 2.203 --- typeobject.c 6 Feb 2003 15:22:49 -0000 2.204 *************** *** 641,645 **** /* UnTrack and re-Track around the trashcan macro, alas */ ! /* See explanation at end of funtion for full disclosure */ PyObject_GC_UnTrack(self); ++_PyTrash_delete_nesting; --- 641,645 ---- /* UnTrack and re-Track around the trashcan macro, alas */ ! /* See explanation at end of function for full disclosure */ PyObject_GC_UnTrack(self); ++_PyTrash_delete_nesting; From jhylton@users.sourceforge.net Thu Feb 6 16:00:37 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Thu, 06 Feb 2003 08:00:37 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.642,1.643 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv19916 Modified Files: NEWS Log Message: Add news item about __module__ attribute on functions. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.642 retrieving revision 1.643 diff -C2 -d -r1.642 -r1.643 *** NEWS 5 Feb 2003 18:29:34 -0000 1.642 --- NEWS 6 Feb 2003 16:00:15 -0000 1.643 *************** *** 31,34 **** --- 31,42 ---- See SF bug #676155. + - Function objects now have an __module__ attribute that is bound to + the name of the module in which the function was defined. This + attribute is used by pickle.whichmodule(), which changes the + behavior of whichmodule slightly. In Python 2.2 whichmodule() + returns "__main__" for functions that are not defined at the + top-level of a module (examples: methods, nested functions). Now + whichmodule() will return the proper module name. + Extension modules ----------------- From gvanrossum@users.sourceforge.net Thu Feb 6 16:16:53 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 06 Feb 2003 08:16:53 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.643,1.644 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv29015 Modified Files: NEWS Log Message: Clarify that __module__ applies to various type of functions. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.643 retrieving revision 1.644 diff -C2 -d -r1.643 -r1.644 *** NEWS 6 Feb 2003 16:00:15 -0000 1.643 --- NEWS 6 Feb 2003 16:16:50 -0000 1.644 *************** *** 31,41 **** See SF bug #676155. ! - Function objects now have an __module__ attribute that is bound to the name of the module in which the function was defined. This ! attribute is used by pickle.whichmodule(), which changes the ! behavior of whichmodule slightly. In Python 2.2 whichmodule() ! returns "__main__" for functions that are not defined at the ! top-level of a module (examples: methods, nested functions). Now ! whichmodule() will return the proper module name. Extension modules --- 31,42 ---- See SF bug #676155. ! - Function objects now have a __module__ attribute that is bound to the name of the module in which the function was defined. This ! applies for C functions and methods as well as functions and methods ! defined in Python. This attribute is used by pickle.whichmodule(), ! which changes the behavior of whichmodule slightly. In Python 2.2 ! whichmodule() returns "__main__" for functions that are not defined ! at the top-level of a module (examples: methods, nested functions). ! Now whichmodule() will return the proper module name. Extension modules From jhylton@users.sourceforge.net Thu Feb 6 16:22:04 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Thu, 06 Feb 2003 08:22:04 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.144,1.145 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv31570 Modified Files: pickle.py Log Message: Replace hasattr() + getattr() with single getattr() and default value. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.144 retrieving revision 1.145 diff -C2 -d -r1.144 -r1.145 *** pickle.py 4 Feb 2003 01:54:48 -0000 1.144 --- pickle.py 6 Feb 2003 16:22:01 -0000 1.145 *************** *** 944,949 **** continue # skip dummy package entries if name != '__main__' and \ ! hasattr(module, funcname) and \ ! getattr(module, funcname) is func: break else: --- 944,948 ---- continue # skip dummy package entries if name != '__main__' and \ ! getattr(module, funcname, None) is func: break else: From jhylton@users.sourceforge.net Thu Feb 6 16:23:03 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Thu, 06 Feb 2003 08:23:03 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.145,1.146 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv32272 Modified Files: pickle.py Log Message: No need for a continuation line. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.145 retrieving revision 1.146 diff -C2 -d -r1.145 -r1.146 *** pickle.py 6 Feb 2003 16:22:01 -0000 1.145 --- pickle.py 6 Feb 2003 16:23:01 -0000 1.146 *************** *** 943,948 **** if module is None: continue # skip dummy package entries ! if name != '__main__' and \ ! getattr(module, funcname, None) is func: break else: --- 943,947 ---- if module is None: continue # skip dummy package entries ! if name != '__main__' and getattr(module, funcname, None) is func: break else: From tim_one@users.sourceforge.net Thu Feb 6 16:32:34 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 06 Feb 2003 08:32:34 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime test_datetime.py,1.111,1.112 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv4898 Modified Files: test_datetime.py Log Message: SF bug 680864: test_datetime fails for non-unix epoch Apparently MAC OS 9 doesn't have POSIX-conforming timestamps. A test fails as a result, but at least for this specific test it's easy enough to get the POSIX epoch out of it. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.111 retrieving revision 1.112 diff -C2 -d -r1.111 -r1.112 *** test_datetime.py 5 Feb 2003 22:29:00 -0000 1.111 --- test_datetime.py 6 Feb 2003 16:32:31 -0000 1.112 *************** *** 2258,2273 **** # Try to make sure tz= actually does some conversion. ! timestamp = 1000000000 # 2001-09-09 01:46:40 UTC, give or take ! utc = FixedOffset(0, "utc", 0) ! expected = datetime(2001, 9, 9, 1, 46, 40) ! got = datetime.utcfromtimestamp(timestamp) ! # We don't support leap seconds, but maybe the platfrom insists ! # on using them, so don't demand exact equality). ! self.failUnless(abs(got - expected) < timedelta(minutes=1)) ! ! est = FixedOffset(-5*60, "est", 0) ! expected -= timedelta(hours=5) ! got = datetime.fromtimestamp(timestamp, est).replace(tzinfo=None) ! self.failUnless(abs(got - expected) < timedelta(minutes=1)) def test_tzinfo_utcnow(self): --- 2258,2272 ---- # Try to make sure tz= actually does some conversion. ! timestamp = 1000000000 ! utcdatetime = datetime.utcfromtimestamp(timestamp) ! # In POSIX (epoch 1970), that's 2001-09-09 01:46:40 UTC, give or take. ! # But on some flavor of Mac, it's nowhere near that. So we can't have ! # any idea here what time that actually is, we can only test that ! # relative changes match. ! utcoffset = timedelta(hours=-15, minutes=39) # arbitrary, but not zero ! tz = FixedOffset(utcoffset, "tz", 0) ! expected = utcdatetime + utcoffset ! got = datetime.fromtimestamp(timestamp, tz) ! self.assertEqual(expected, got.replace(tzinfo=None)) def test_tzinfo_utcnow(self): From tim_one@users.sourceforge.net Thu Feb 6 16:42:17 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 06 Feb 2003 08:42:17 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv10637/python/Lib/test Modified Files: test_datetime.py Log Message: SF bug 680864: test_datetime fails for non-unix epoch Apparently MAC OS 9 doesn't have POSIX-conforming timestamps. A test fails as a result, but at least for this specific test it's easy enough to get the POSIX epoch out of it. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** test_datetime.py 5 Feb 2003 04:08:07 -0000 1.35 --- test_datetime.py 6 Feb 2003 16:42:14 -0000 1.36 *************** *** 2258,2273 **** # Try to make sure tz= actually does some conversion. ! timestamp = 1000000000 # 2001-09-09 01:46:40 UTC, give or take ! utc = FixedOffset(0, "utc", 0) ! expected = datetime(2001, 9, 9, 1, 46, 40) ! got = datetime.utcfromtimestamp(timestamp) ! # We don't support leap seconds, but maybe the platfrom insists ! # on using them, so don't demand exact equality). ! self.failUnless(abs(got - expected) < timedelta(minutes=1)) ! ! est = FixedOffset(-5*60, "est", 0) ! expected -= timedelta(hours=5) ! got = datetime.fromtimestamp(timestamp, est).replace(tzinfo=None) ! self.failUnless(abs(got - expected) < timedelta(minutes=1)) def test_tzinfo_utcnow(self): --- 2258,2272 ---- # Try to make sure tz= actually does some conversion. ! timestamp = 1000000000 ! utcdatetime = datetime.utcfromtimestamp(timestamp) ! # In POSIX (epoch 1970), that's 2001-09-09 01:46:40 UTC, give or take. ! # But on some flavor of Mac, it's nowhere near that. So we can't have ! # any idea here what time that actually is, we can only test that ! # relative changes match. ! utcoffset = timedelta(hours=-15, minutes=39) # arbitrary, but not zero ! tz = FixedOffset(utcoffset, "tz", 0) ! expected = utcdatetime + utcoffset ! got = datetime.fromtimestamp(timestamp, tz) ! self.assertEqual(expected, got.replace(tzinfo=None)) def test_tzinfo_utcnow(self): From akuchling@users.sourceforge.net Thu Feb 6 17:42:47 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Thu, 06 Feb 2003 09:42:47 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_filecmp.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv8315 Added Files: test_filecmp.py Log Message: Add test suite for filecmp.py, after some discussion on bug #680494. Right now the test cases create a files and a directory in the temp. directory. Raymond suggested checking files in to the test/ directory, simplifying the setup/teardown methods; is that worth doing? --- NEW FILE: test_filecmp.py --- import os, filecmp, shutil, tempfile import unittest from test import test_support class FileCompareTestCase(unittest.TestCase): def setUp(self): self.name = test_support.TESTFN self.name_same = test_support.TESTFN + '-same' self.name_diff = test_support.TESTFN + '-diff' data = 'Contents of file go here.\n' for name in [self.name, self.name_same, self.name_diff]: output = open(name, 'w') output.write(data) output.close() output = open(self.name_diff, 'a+') output.write('An extra line.\n') output.close() self.dir = tempfile.gettempdir() def tearDown(self): os.unlink(self.name) os.unlink(self.name_same) os.unlink(self.name_diff) def test_matching(self): self.failUnless(filecmp.cmp(self.name, self.name_same), "Comparing file to itself fails") self.failUnless(filecmp.cmp(self.name, self.name_same, shallow=False), "Comparing file to itself fails") self.failUnless(filecmp.cmp(self.name, self.name, shallow=False), "Comparing file to identical file fails") self.failUnless(filecmp.cmp(self.name, self.name), "Comparing file to identical file fails") def test_different(self): self.failIf(filecmp.cmp(self.name, self.name_diff), "Mismatched files compare as equal") self.failIf(filecmp.cmp(self.name, self.dir), "File and directory compare as equal") class DirCompareTestCase(unittest.TestCase): def setUp(self): tmpdir = tempfile.gettempdir() self.dir = os.path.join(tmpdir, 'dir') self.dir_same = os.path.join(tmpdir, 'dir-same') self.dir_diff = os.path.join(tmpdir, 'dir-diff') data = 'Contents of file go here.\n' for dir in [self.dir, self.dir_same, self.dir_diff]: os.mkdir(dir) output = open(os.path.join(dir, 'file'), 'w') output.write(data) output.close() output = open(os.path.join(self.dir_diff, 'file2'), 'w') output.write('An extra file.\n') output.close() def tearDown(self): shutil.rmtree(self.dir) shutil.rmtree(self.dir_same) shutil.rmtree(self.dir_diff) def test_cmpfiles(self): self.failUnless(filecmp.cmpfiles(self.dir, self.dir, ['file']) == (['file'], [], []), "Comparing directory to itself fails") self.failUnless(filecmp.cmpfiles(self.dir, self.dir_same, ['file']) == (['file'], [], []), "Comparing directory to same fails") # Try it with shallow=False self.failUnless(filecmp.cmpfiles(self.dir, self.dir, ['file'], shallow=False) == (['file'], [], []), "Comparing directory to itself fails") self.failUnless(filecmp.cmpfiles(self.dir, self.dir_same, ['file'], shallow=False), "Comparing directory to same fails") # Add different file2 output = open(os.path.join(self.dir, 'file2'), 'w') output.write('Different contents.\n') output.close() self.failIf(filecmp.cmpfiles(self.dir, self.dir_same, ['file', 'file2']) == (['file'], ['file2'], []), "Comparing mismatched directories fails") def test_dircmp(self): # Check attributes for comparison of two identical directories d = filecmp.dircmp(self.dir, self.dir_same) self.failUnless(d.left_list == d.right_list == ['file']) self.failUnless(d.common == ['file']) self.failUnless(d.left_only == d.right_only == []) self.failUnless(d.same_files == ['file']) self.failUnless(d.diff_files == []) # Check attributes for comparison of two different directories d = filecmp.dircmp(self.dir, self.dir_diff) self.failUnless(d.left_list == ['file']) self.failUnless(d.right_list == ['file', 'file2']) self.failUnless(d.common == ['file']) self.failUnless(d.left_only == []) self.failUnless(d.right_only == ['file2']) self.failUnless(d.same_files == ['file']) self.failUnless(d.diff_files == []) # Add different file2 output = open(os.path.join(self.dir, 'file2'), 'w') output.write('Different contents.\n') output.close() d = filecmp.dircmp(self.dir, self.dir_diff) self.failUnless(d.same_files == ['file']) self.failUnless(d.diff_files == ['file2']) def test_main(): suite = unittest.TestSuite() for cls in FileCompareTestCase, DirCompareTestCase: suite.addTest(unittest.makeSuite(cls)) test_support.run_suite(suite) if __name__ == "__main__": test_main() From akuchling@users.sourceforge.net Thu Feb 6 17:50:03 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Thu, 06 Feb 2003 09:50:03 -0800 Subject: [Python-checkins] python/dist/src/Lib filecmp.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv12521 Modified Files: filecmp.py Log Message: [Bug #680494] filecmp.py uses obsolete statcache module. Simply replace all uses of statcache with os.stat. Should I add a DeprecationWarning triggered if the use_statcache argument is supplied, so we can remove it in 2.4? Index: filecmp.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/filecmp.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** filecmp.py 2 Jun 2002 18:55:56 -0000 1.13 --- filecmp.py 6 Feb 2003 17:50:01 -0000 1.14 *************** *** 12,16 **** import os import stat - import statcache __all__ = ["cmp","dircmp","cmpfiles"] --- 12,15 ---- *************** *** 31,36 **** defaults to 1. ! use_statcache -- Do not stat() each file directly: go through ! the statcache module for more efficiency. Return value: --- 30,34 ---- defaults to 1. ! use_statcache -- obsolete argument. Return value: *************** *** 40,53 **** This function uses a cache for past comparisons and the results, with a cache invalidation mechanism relying on stale signatures. - Of course, if 'use_statcache' is true, this mechanism is defeated, - and the cache will never grow stale. """ ! if use_statcache: ! stat_function = statcache.stat ! else: ! stat_function = os.stat ! s1 = _sig(stat_function(f1)) ! s2 = _sig(stat_function(f2)) if s1[0] != stat.S_IFREG or s2[0] != stat.S_IFREG: return False --- 38,45 ---- This function uses a cache for past comparisons and the results, with a cache invalidation mechanism relying on stale signatures. """ ! s1 = _sig(os.stat(f1)) ! s2 = _sig(os.stat(f2)) if s1[0] != stat.S_IFREG or s2[0] != stat.S_IFREG: return False *************** *** 189,198 **** ok = 1 try: ! a_stat = statcache.stat(a_path) except os.error, why: # print 'Can\'t stat', a_path, ':', why[1] ok = 0 try: ! b_stat = statcache.stat(b_path) except os.error, why: # print 'Can\'t stat', b_path, ':', why[1] --- 181,190 ---- ok = 1 try: ! a_stat = os.stat(a_path) except os.error, why: # print 'Can\'t stat', a_path, ':', why[1] ok = 0 try: ! b_stat = os.stat(b_path) except os.error, why: # print 'Can\'t stat', b_path, ':', why[1] *************** *** 276,280 **** common -- list of file names found in both directories shallow -- if true, do comparison based solely on stat() information ! use_statcache -- if true, use statcache.stat() instead of os.stat() Returns a tuple of three lists: --- 268,272 ---- common -- list of file names found in both directories shallow -- if true, do comparison based solely on stat() information ! use_statcache -- obsolete argument Returns a tuple of three lists: *************** *** 288,292 **** ax = os.path.join(a, x) bx = os.path.join(b, x) ! res[_cmp(ax, bx, shallow, use_statcache)].append(x) return res --- 280,284 ---- ax = os.path.join(a, x) bx = os.path.join(b, x) ! res[_cmp(ax, bx, shallow)].append(x) return res *************** *** 298,304 **** # 2 for funny cases (can't stat, etc.) # ! def _cmp(a, b, sh, st): try: ! return not abs(cmp(a, b, sh, st)) except os.error: return 2 --- 290,296 ---- # 2 for funny cases (can't stat, etc.) # ! def _cmp(a, b, sh): try: ! return not abs(cmp(a, b, sh)) except os.error: return 2 From gvanrossum@users.sourceforge.net Thu Feb 6 17:52:17 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 06 Feb 2003 09:52:17 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_copy.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv14233 Added Files: test_copy.py Log Message: A test suite for the copy module. This should provide full code coverage. --- NEW FILE: test_copy.py --- """Unit tests for the copy module.""" import sys import copy import unittest from test import test_support class TestCopy(unittest.TestCase): # Attempt full line coverage of copy.py from top to bottom def test_exceptions(self): self.assert_(copy.Error is copy.error) self.assert_(issubclass(copy.Error, Exception)) # The copy() method def test_copy_basic(self): x = 42 y = copy.copy(x) self.assertEqual(x, y) def test_copy_copy(self): class C(object): def __init__(self, foo): self.foo = foo def __copy__(self): return C(self.foo) x = C(42) y = copy.copy(x) self.assertEqual(y.__class__, x.__class__) self.assertEqual(y.foo, x.foo) def test_copy_reduce(self): class C(object): def __reduce__(self): return "" x = C() y = copy.copy(x) self.assert_(y is x) def test_copy_cant(self): class C(object): def __getattribute__(self, name): if name == "__reduce__": raise AttributeError, name return object.__getattribute__(self, name) x = C() self.assertRaises(copy.Error, copy.copy, x) # Type-specific _copy_xxx() methods def test_copy_atomic(self): class Classic: pass class NewStyle(object): pass def f(): pass tests = [None, 42, 2L**100, 3.14, True, False, 1j, "hello", u"hello\u1234", f.func_code, NewStyle, xrange(10), Classic] for x in tests: self.assert_(copy.copy(x) is x, `x`) def test_copy_list(self): x = [1, 2, 3] self.assertEqual(copy.copy(x), x) def test_copy_tuple(self): x = (1, 2, 3) self.assertEqual(copy.copy(x), x) def test_copy_dict(self): x = {"foo": 1, "bar": 2} self.assertEqual(copy.copy(x), x) def test_copy_inst_vanilla(self): class C: def __init__(self, foo): self.foo = foo def __cmp__(self, other): return cmp(self.foo, other.foo) x = C(42) self.assertEqual(copy.copy(x), x) def test_copy_inst_copy(self): class C: def __init__(self, foo): self.foo = foo def __copy__(self): return C(self.foo) def __cmp__(self, other): return cmp(self.foo, other.foo) x = C(42) self.assertEqual(copy.copy(x), x) def test_copy_inst_getinitargs(self): class C: def __init__(self, foo): self.foo = foo def __getinitargs__(self): return (self.foo,) def __cmp__(self, other): return cmp(self.foo, other.foo) x = C(42) self.assertEqual(copy.copy(x), x) def test_copy_inst_getstate(self): class C: def __init__(self, foo): self.foo = foo def __getstate__(self): return {"foo": self.foo} def __cmp__(self, other): return cmp(self.foo, other.foo) x = C(42) self.assertEqual(copy.copy(x), x) def test_copy_inst_setstate(self): class C: def __init__(self, foo): self.foo = foo def __setstate__(self, state): self.foo = state["foo"] def __cmp__(self, other): return cmp(self.foo, other.foo) x = C(42) self.assertEqual(copy.copy(x), x) def test_copy_inst_getstate_setstate(self): class C: def __init__(self, foo): self.foo = foo def __getstate__(self): return self.foo def __setstate__(self, state): self.foo = state def __cmp__(self, other): return cmp(self.foo, other.foo) x = C(42) self.assertEqual(copy.copy(x), x) # The deepcopy() method def test_deepcopy_basic(self): x = 42 y = copy.deepcopy(x) self.assertEqual(y, x) def test_deepcopy_memo(self): x = [] x.append(x) y = copy.deepcopy(x) self.assertEqual(y, x) self.assert_(y is not x) self.assert_(y[0] is not x[0]) self.assert_(y is y[0]) def test_deepcopy_issubclass(self): # XXX Note: there's no way to test the TypeError coming out of # issubclass() -- this can only happen when an extension # module defines a "type" that doesn't formally inherit from # type. class Meta(type): pass class C: __metaclass__ = Meta self.assertEqual(copy.deepcopy(C), C) def test_deepcopy_deepcopy(self): class C(object): def __init__(self, foo): self.foo = foo def __deepcopy__(self, memo=None): return C(self.foo) x = C(42) y = copy.deepcopy(x) self.assertEqual(y.__class__, x.__class__) self.assertEqual(y.foo, x.foo) def test_deepcopy_reduce(self): class C(object): def __reduce__(self): return "" x = C() y = copy.deepcopy(x) self.assert_(y is x) def test_deepcopy_cant(self): class C(object): def __getattribute__(self, name): if name == "__reduce__": raise AttributeError, name return object.__getattribute__(self, name) x = C() self.assertRaises(copy.Error, copy.deepcopy, x) # Type-specific _deepcopy_xxx() methods def test_deepcopy_atomic(self): class Classic: pass class NewStyle(object): pass def f(): pass tests = [None, 42, 2L**100, 3.14, True, False, 1j, "hello", u"hello\u1234", f.func_code, NewStyle, xrange(10)] for x in tests: self.assert_(copy.deepcopy(x) is x, `x`) def test_deepcopy_list(self): x = [[1, 2], 3] y = copy.deepcopy(x) self.assertEqual(y, x) self.assert_(x is not y) self.assert_(x[0] is not y[0]) def test_deepcopy_tuple(self): x = ([1, 2], 3) y = copy.deepcopy(x) self.assertEqual(y, x) self.assert_(x is not y) self.assert_(x[0] is not y[0]) def test_deepcopy_dict(self): x = {"foo": [1, 2], "bar": 3} y = copy.deepcopy(x) self.assertEqual(y, x) self.assert_(x is not y) self.assert_(x["foo"] is not y["foo"]) def test_deepcopy_keepalive(self): memo = {} x = 42 y = copy.deepcopy(x, memo) self.assert_(memo[id(x)] is x) def test_deepcopy_inst_vanilla(self): class C: def __init__(self, foo): self.foo = foo def __cmp__(self, other): return cmp(self.foo, other.foo) x = C([42]) y = copy.deepcopy(x) self.assertEqual(y, x) self.assert_(y.foo is not x.foo) def test_deepcopy_inst_deepcopy(self): class C: def __init__(self, foo): self.foo = foo def __deepcopy__(self, memo): return C(copy.deepcopy(self.foo, memo)) def __cmp__(self, other): return cmp(self.foo, other.foo) x = C([42]) y = copy.deepcopy(x) self.assertEqual(y, x) self.assert_(y is not x) self.assert_(y.foo is not x.foo) def test_deepcopy_inst_getinitargs(self): class C: def __init__(self, foo): self.foo = foo def __getinitargs__(self): return (self.foo,) def __cmp__(self, other): return cmp(self.foo, other.foo) x = C([42]) y = copy.deepcopy(x) self.assertEqual(y, x) self.assert_(y is not x) self.assert_(y.foo is not x.foo) def test_deepcopy_inst_getstate(self): class C: def __init__(self, foo): self.foo = foo def __getstate__(self): return {"foo": self.foo} def __cmp__(self, other): return cmp(self.foo, other.foo) x = C([42]) y = copy.deepcopy(x) self.assertEqual(y, x) self.assert_(y is not x) self.assert_(y.foo is not x.foo) def test_deepcopy_inst_setstate(self): class C: def __init__(self, foo): self.foo = foo def __setstate__(self, state): self.foo = state["foo"] def __cmp__(self, other): return cmp(self.foo, other.foo) x = C([42]) y = copy.deepcopy(x) self.assertEqual(y, x) self.assert_(y is not x) self.assert_(y.foo is not x.foo) def test_deepcopy_inst_getstate_setstate(self): class C: def __init__(self, foo): self.foo = foo def __getstate__(self): return self.foo def __setstate__(self, state): self.foo = state def __cmp__(self, other): return cmp(self.foo, other.foo) x = C([42]) y = copy.deepcopy(x) self.assertEqual(y, x) self.assert_(y is not x) self.assert_(y.foo is not x.foo) # _reconstruct() def test_reconstruct_string(self): class C(object): def __reduce__(self): return "" x = C() y = copy.copy(x) self.assert_(y is x) y = copy.deepcopy(x) self.assert_(y is x) def test_reconstruct_nostate(self): class C(object): def __reduce__(self): return (C, ()) x = C() x.foo = 42 y = copy.copy(x) self.assert_(y.__class__ is x.__class__) y = copy.deepcopy(x) self.assert_(y.__class__ is x.__class__) def test_reconstruct_state(self): class C(object): def __reduce__(self): return (C, (), self.__dict__) def __cmp__(self, other): return cmp(self.__dict__, other.__dict__) x = C() x.foo = [42] y = copy.copy(x) self.assertEqual(y, x) y = copy.deepcopy(x) self.assertEqual(y, x) self.assert_(y.foo is not x.foo) def test_reconstruct_state_setstate(self): class C(object): def __reduce__(self): return (C, (), self.__dict__) def __setstate__(self, state): self.__dict__.update(state) def __cmp__(self, other): return cmp(self.__dict__, other.__dict__) x = C() x.foo = [42] y = copy.copy(x) self.assertEqual(y, x) y = copy.deepcopy(x) self.assertEqual(y, x) self.assert_(y.foo is not x.foo) def test_main(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestCopy)) test_support.run_suite(suite) if __name__ == "__main__": test_main() From akuchling@users.sourceforge.net Thu Feb 6 17:57:17 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Thu, 06 Feb 2003 09:57:17 -0800 Subject: [Python-checkins] python/nondist/peps pep-0042.txt,1.67,1.68 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv16637 Modified Files: pep-0042.txt Log Message: Add a wish Index: pep-0042.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0042.txt,v retrieving revision 1.67 retrieving revision 1.68 diff -C2 -d -r1.67 -r1.68 *** pep-0042.txt 5 Feb 2003 20:21:49 -0000 1.67 --- pep-0042.txt 6 Feb 2003 17:57:14 -0000 1.68 *************** *** 242,245 **** --- 242,249 ---- http://www.python.org/sf/405554 + - Distutils should deduce dependencies for .c and .h files. + + http://www.python.org/sf/472881 + C API wishes From akuchling@users.sourceforge.net Thu Feb 6 18:04:54 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Thu, 06 Feb 2003 10:04:54 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libpopen2.tex,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv22317 Modified Files: libpopen2.tex Log Message: Typo fixes Index: libpopen2.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libpopen2.tex,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** libpopen2.tex 6 Dec 2002 16:45:05 -0000 1.18 --- libpopen2.tex 6 Feb 2003 18:04:43 -0000 1.19 *************** *** 58,62 **** \function{popen3()} factory functions described above. ! If not using one off the helper functions to create \class{Popen3} objects, the parameter \var{cmd} is the shell command to execute in a sub-process. The \var{capturestderr} flag, if true, specifies that --- 58,62 ---- \function{popen3()} factory functions described above. ! If not using one of the helper functions to create \class{Popen3} objects, the parameter \var{cmd} is the shell command to execute in a sub-process. The \var{capturestderr} flag, if true, specifies that *************** *** 130,134 **** When reading output from a child process that writes a lot of data to standard error while the parent is reading from the child's standard ! out, a deadlock can occur. A similar situation can occur with other combinations of reads and writes. The essential factors are that more than \constant{_PC_PIPE_BUF} bytes are being written by one process in --- 130,134 ---- When reading output from a child process that writes a lot of data to standard error while the parent is reading from the child's standard ! output, a deadlock can occur. A similar situation can occur with other combinations of reads and writes. The essential factors are that more than \constant{_PC_PIPE_BUF} bytes are being written by one process in From gvanrossum@users.sourceforge.net Thu Feb 6 18:18:26 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 06 Feb 2003 10:18:26 -0800 Subject: [Python-checkins] python/dist/src/Lib copy.py,1.30,1.31 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv827 Modified Files: copy.py Log Message: Support __reduce__ returning a 4-tuple or 5-tuple. Index: copy.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** copy.py 16 Jan 2003 10:40:00 -0000 1.30 --- copy.py 6 Feb 2003 18:18:23 -0000 1.31 *************** *** 298,302 **** memo = {} n = len(info) ! assert n in (2, 3) callable, args = info[:2] if n > 2: --- 298,302 ---- memo = {} n = len(info) ! assert n in (2, 3, 4, 5) callable, args = info[:2] if n > 2: *************** *** 304,310 **** --- 304,329 ---- else: state = {} + if n > 3: + listiter = info[3] + else: + listiter = None + if n > 4: + dictiter = info[4] + else: + dictiter = None if deep: args = deepcopy(args, memo) y = callable(*args) + if listiter is not None: + for item in listiter: + if deep: + item = deepcopy(item, memo) + y.append(item) + if dictiter is not None: + for key, value in dictiter: + if deep: + key = deepcopy(key, memo) + value = deepcopy(value, memo) + y[key] = value if state: if deep: From gvanrossum@users.sourceforge.net Thu Feb 6 18:18:26 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 06 Feb 2003 10:18:26 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_copy.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv827/test Modified Files: test_copy.py Log Message: Support __reduce__ returning a 4-tuple or 5-tuple. Index: test_copy.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_copy.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_copy.py 6 Feb 2003 17:52:15 -0000 1.1 --- test_copy.py 6 Feb 2003 18:18:23 -0000 1.2 *************** *** 376,379 **** --- 376,415 ---- self.assert_(y.foo is not x.foo) + # Additions for Python 2.3 and pickle protocol 2 + + def test_reduce_4tuple(self): + class C(list): + def __reduce__(self): + return (C, (), self.__dict__, iter(self)) + def __cmp__(self, other): + return (cmp(list(self), list(other)) or + cmp(self.__dict__, other.__dict__)) + x = C([[1, 2], 3]) + y = copy.copy(x) + self.assertEqual(x, y) + self.assert_(x is not y) + self.assert_(x[0] is y[0]) + y = copy.deepcopy(x) + self.assertEqual(x, y) + self.assert_(x is not y) + self.assert_(x[0] is not y[0]) + + def test_reduce_5tuple(self): + class C(dict): + def __reduce__(self): + return (C, (), self.__dict__, None, self.iteritems()) + def __cmp__(self, other): + return (cmp(dict(self), list(dict)) or + cmp(self.__dict__, other.__dict__)) + x = C([("foo", [1, 2]), ("bar", 3)]) + y = copy.copy(x) + self.assertEqual(x, y) + self.assert_(x is not y) + self.assert_(x["foo"] is y["foo"]) + y = copy.deepcopy(x) + self.assertEqual(x, y) + self.assert_(x is not y) + self.assert_(x["foo"] is not y["foo"]) + def test_main(): suite = unittest.TestSuite() From mwh@users.sourceforge.net Thu Feb 6 18:37:14 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Thu, 06 Feb 2003 10:37:14 -0800 Subject: [Python-checkins] python/dist/src/Doc/api newtypes.tex,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory sc8-pr-cvs1:/tmp/cvs-serv11136/api Modified Files: newtypes.tex Log Message: Correct lie about METH_NOARGS functions. Backport candidate. Index: newtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/newtypes.tex,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** newtypes.tex 31 Jan 2003 05:44:25 -0000 1.19 --- newtypes.tex 6 Feb 2003 18:37:11 -0000 1.20 *************** *** 245,249 **** (often called \var{args}) is a tuple object representing all arguments. This parameter is typically processed using ! \cfunction{PyArg_ParseTuple()}. \end{datadesc} --- 245,249 ---- (often called \var{args}) is a tuple object representing all arguments. This parameter is typically processed using ! \cfunction{PyArg_ParseTuple()} or \cfunction{PyArg_UnpackTuple}. \end{datadesc} *************** *** 260,267 **** Methods without parameters don't need to check whether arguments are given if they are listed with the \constant{METH_NOARGS} flag. They ! need to be of type \ctype{PyNoArgsFunction}: they expect a single ! single \ctype{PyObject*} as a parameter. When used with object ! methods, this parameter is typically named \code{self} and will hold ! a reference to the object instance. \end{datadesc} --- 260,267 ---- Methods without parameters don't need to check whether arguments are given if they are listed with the \constant{METH_NOARGS} flag. They ! need to be of type \ctype{PyCFunction}. When used with object ! methods, the first parameter is typically named \code{self} and will ! hold a reference to the object instance. In all cases the second ! parameter will be \NULL. \end{datadesc} From mwh@users.sourceforge.net Thu Feb 6 18:38:14 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Thu, 06 Feb 2003 10:38:14 -0800 Subject: [Python-checkins] python/dist/src/Doc/ext extending.tex,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ext In directory sc8-pr-cvs1:/tmp/cvs-serv11801/ext Modified Files: extending.tex Log Message: Remove another lie. Index: extending.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ext/extending.tex,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** extending.tex 19 Jul 2002 06:55:41 -0000 1.22 --- extending.tex 6 Feb 2003 18:38:11 -0000 1.23 *************** *** 819,826 **** this is done using the functions \cfunction{malloc()} and \cfunction{free()}. In \Cpp, the operators \keyword{new} and ! \keyword{delete} are used with essentially the same meaning; they are ! actually implemented using \cfunction{malloc()} and ! \cfunction{free()}, so we'll restrict the following discussion to the ! latter. Every block of memory allocated with \cfunction{malloc()} should --- 819,824 ---- this is done using the functions \cfunction{malloc()} and \cfunction{free()}. In \Cpp, the operators \keyword{new} and ! \keyword{delete} are used with essentially the same meaning and ! we'll restrict the following discussion to the latter. Every block of memory allocated with \cfunction{malloc()} should From gvanrossum@users.sourceforge.net Thu Feb 6 19:30:42 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 06 Feb 2003 11:30:42 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.146,1.147 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv5442 Modified Files: pickle.py Log Message: Remove a debug print statement. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.146 retrieving revision 1.147 diff -C2 -d -r1.146 -r1.147 *** pickle.py 6 Feb 2003 16:23:01 -0000 1.146 --- pickle.py 6 Feb 2003 19:30:38 -0000 1.147 *************** *** 489,493 **** "without defining __getstate__ " "cannot be pickled"): - print repr(str(err)) raise # Not that specific exception getstate = None --- 489,492 ---- From akuchling@users.sourceforge.net Thu Feb 6 19:38:51 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Thu, 06 Feb 2003 11:38:51 -0800 Subject: [Python-checkins] python/dist/src/Lib filecmp.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv9270 Modified Files: filecmp.py Log Message: Add DeprecationWarning when use_statcache argument is supplied Fix use of GetoptError, so demo() now works Index: filecmp.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/filecmp.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** filecmp.py 6 Feb 2003 17:50:01 -0000 1.14 --- filecmp.py 6 Feb 2003 19:38:45 -0000 1.15 *************** *** 5,9 **** Functions: ! cmp(f1, f2, shallow=1, use_statcache=0) -> int cmpfiles(a, b, common) -> ([], [], []) --- 5,9 ---- Functions: ! cmp(f1, f2, shallow=1) -> int cmpfiles(a, b, common) -> ([], [], []) *************** *** 12,15 **** --- 12,16 ---- import os import stat + import warnings __all__ = ["cmp","dircmp","cmpfiles"] *************** *** 18,22 **** BUFSIZE=8*1024 ! def cmp(f1, f2, shallow=1, use_statcache=0): """Compare two files. --- 19,23 ---- BUFSIZE=8*1024 ! def cmp(f1, f2, shallow=1, use_statcache=None): """Compare two files. *************** *** 40,43 **** --- 41,48 ---- """ + if use_statcache is not None: + warnings.warn("use_statcache argument is deprecated", + DeprecationWarning) + s1 = _sig(os.stat(f1)) s2 = _sig(os.stat(f2)) *************** *** 262,266 **** ! def cmpfiles(a, b, common, shallow=1, use_statcache=0): """Compare common files in two directories. --- 267,271 ---- ! def cmpfiles(a, b, common, shallow=1, use_statcache=None): """Compare common files in two directories. *************** *** 276,279 **** --- 281,287 ---- """ + if use_statcache is not None: + warnings.warn("use_statcache argument is deprecated", + DeprecationWarning) res = ([], [], []) for x in common: *************** *** 313,317 **** options, args = getopt.getopt(sys.argv[1:], 'r') if len(args) != 2: ! raise getopt.error, 'need exactly two args' dd = dircmp(args[0], args[1]) if ('-r', '') in options: --- 321,325 ---- options, args = getopt.getopt(sys.argv[1:], 'r') if len(args) != 2: ! raise getopt.GetoptError('need exactly two args', None) dd = dircmp(args[0], args[1]) if ('-r', '') in options: From akuchling@users.sourceforge.net Thu Feb 6 19:52:59 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Thu, 06 Feb 2003 11:52:59 -0800 Subject: [Python-checkins] python/dist/src/Lib getopt.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv15856 Modified Files: getopt.py Log Message: A few naughty external scripts do 'raise getopt.error, "blah"', and now crash because two arguments are expected. Add a default value to keep those scripts running. Index: getopt.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/getopt.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** getopt.py 4 Aug 2002 17:22:59 -0000 1.23 --- getopt.py 6 Feb 2003 19:52:56 -0000 1.24 *************** *** 40,44 **** opt = '' msg = '' ! def __init__(self, msg, opt): self.msg = msg self.opt = opt --- 40,44 ---- opt = '' msg = '' ! def __init__(self, msg, opt=''): self.msg = msg self.opt = opt From gvanrossum@users.sourceforge.net Thu Feb 6 19:53:24 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 06 Feb 2003 11:53:24 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_copy.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv15843/test Modified Files: test_copy.py Log Message: Support all the new stuff supported by the new pickle code: - subclasses of list or dict - __reduce__ returning a 4-tuple or 5-tuple - slots Index: test_copy.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_copy.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_copy.py 6 Feb 2003 18:18:23 -0000 1.2 --- test_copy.py 6 Feb 2003 19:53:22 -0000 1.3 *************** *** 42,50 **** def test_copy_cant(self): ! class C(object): def __getattribute__(self, name): if name == "__reduce__": raise AttributeError, name return object.__getattribute__(self, name) x = C() self.assertRaises(copy.Error, copy.copy, x) --- 42,52 ---- def test_copy_cant(self): ! class Meta(type): def __getattribute__(self, name): if name == "__reduce__": raise AttributeError, name return object.__getattribute__(self, name) + class C: + __metaclass__ = Meta x = C() self.assertRaises(copy.Error, copy.copy, x) *************** *** 190,198 **** def test_deepcopy_cant(self): ! class C(object): def __getattribute__(self, name): if name == "__reduce__": raise AttributeError, name return object.__getattribute__(self, name) x = C() self.assertRaises(copy.Error, copy.deepcopy, x) --- 192,202 ---- def test_deepcopy_cant(self): ! class Meta(type): def __getattribute__(self, name): if name == "__reduce__": raise AttributeError, name return object.__getattribute__(self, name) + class C: + __metaclass__ = Meta x = C() self.assertRaises(copy.Error, copy.deepcopy, x) *************** *** 411,414 **** --- 415,457 ---- self.assert_(x is not y) self.assert_(x["foo"] is not y["foo"]) + + def test_copy_slots(self): + class C(object): + __slots__ = ["foo"] + x = C() + x.foo = [42] + y = copy.copy(x) + self.assert_(x.foo is y.foo) + + def test_deepcopy_slots(self): + class C(object): + __slots__ = ["foo"] + x = C() + x.foo = [42] + y = copy.deepcopy(x) + self.assertEqual(x.foo, y.foo) + self.assert_(x.foo is not y.foo) + + def test_copy_list_subclass(self): + class C(list): + pass + x = C([[1, 2], 3]) + x.foo = [4, 5] + y = copy.copy(x) + self.assertEqual(list(x), list(y)) + self.assertEqual(x.foo, y.foo) + self.assert_(x[0] is y[0]) + self.assert_(x.foo is y.foo) + + def test_deepcopy_list_subclass(self): + class C(list): + pass + x = C([[1, 2], 3]) + x.foo = [4, 5] + y = copy.deepcopy(x) + self.assertEqual(list(x), list(y)) + self.assertEqual(x.foo, y.foo) + self.assert_(x[0] is not y[0]) + self.assert_(x.foo is not y.foo) def test_main(): From gvanrossum@users.sourceforge.net Thu Feb 6 19:53:24 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 06 Feb 2003 11:53:24 -0800 Subject: [Python-checkins] python/dist/src/Lib copy.py,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv15843 Modified Files: copy.py Log Message: Support all the new stuff supported by the new pickle code: - subclasses of list or dict - __reduce__ returning a 4-tuple or 5-tuple - slots Index: copy.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** copy.py 6 Feb 2003 18:18:23 -0000 1.31 --- copy.py 6 Feb 2003 19:53:22 -0000 1.32 *************** *** 8,12 **** x = copy.deepcopy(y) # make a deep copy of y ! For module specific errors, copy.error is raised. The difference between shallow and deep copying is only relevant for --- 8,12 ---- x = copy.deepcopy(y) # make a deep copy of y ! For module specific errors, copy.Error is raised. The difference between shallow and deep copying is only relevant for *************** *** 52,55 **** --- 52,56 ---- import types + from pickle import _slotnames class Error(Exception): *************** *** 62,66 **** PyStringMap = None ! __all__ = ["Error", "error", "copy", "deepcopy"] def copy(x): --- 63,67 ---- PyStringMap = None ! __all__ = ["Error", "copy", "deepcopy"] def copy(x): *************** *** 77,86 **** except AttributeError: try: ! reductor = x.__reduce__ except AttributeError: ! raise error, \ ! "un(shallow)copyable object of type %s" % type(x) else: ! y = _reconstruct(x, reductor(), 0) else: y = copier() --- 78,88 ---- except AttributeError: try: ! reductor = x.__class__.__reduce__ ! if reductor == object.__reduce__: ! reductor = _better_reduce except AttributeError: ! raise Error("un(shallow)copyable object of type %s" % type(x)) else: ! y = _reconstruct(x, reductor(x), 0) else: y = copier() *************** *** 89,92 **** --- 91,135 ---- return y + def __newobj__(cls, *args): + return cls.__new__(cls, *args) + + def _better_reduce(obj): + cls = obj.__class__ + getnewargs = getattr(obj, "__getnewargs__", None) + if getnewargs: + args = getnewargs() + else: + args = () + getstate = getattr(obj, "__getstate__", None) + if getstate: + try: + state = getstate() + except TypeError, err: + # XXX Catch generic exception caused by __slots__ + if str(err) != ("a class that defines __slots__ " + "without defining __getstate__ " + "cannot be pickled"): + raise # Not that specific exception + getstate = None + if not getstate: + state = getattr(obj, "__dict__", None) + names = _slotnames(cls) + if names: + slots = {} + nil = [] + for name in names: + value = getattr(obj, name, nil) + if value is not nil: + slots[name] = value + if slots: + state = (state, slots) + listitems = dictitems = None + if isinstance(obj, list): + listitems = iter(obj) + elif isinstance(obj, dict): + dictitems = obj.iteritems() + return __newobj__, (cls, args), state, listitems, dictitems + + _copy_dispatch = d = {} *************** *** 176,185 **** except AttributeError: try: ! reductor = x.__reduce__ except AttributeError: ! raise error, \ ! "un-deep-copyable object of type %s" % type(x) else: ! y = _reconstruct(x, reductor(), 1, memo) else: y = copier(memo) --- 219,230 ---- except AttributeError: try: ! reductor = x.__class__.__reduce__ ! if reductor == object.__reduce__: ! reductor = _better_reduce except AttributeError: ! raise Error("un(shallow)copyable object of type %s" % ! type(x)) else: ! y = _reconstruct(x, reductor(x), 1, memo) else: y = copier(memo) *************** *** 332,336 **** y.__setstate__(state) else: ! y.__dict__.update(state) return y --- 377,389 ---- y.__setstate__(state) else: ! if isinstance(state, tuple) and len(state) == 2: ! state, slotstate = state ! else: ! slotstate = None ! if state is not None: ! y.__dict__.update(state) ! if slotstate is not None: ! for key, value in slotstate.iteritems(): ! setattr(y, key, value) return y From akuchling@users.sourceforge.net Thu Feb 6 19:55:37 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Thu, 06 Feb 2003 11:55:37 -0800 Subject: [Python-checkins] python/dist/src/Tools/scripts findlinksto.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv17760 Modified Files: findlinksto.py Log Message: Use new name for GetoptError, and pass it two arguments Use re module instead of regex Index: findlinksto.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/findlinksto.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** findlinksto.py 17 Jan 2001 08:48:39 -0000 1.8 --- findlinksto.py 6 Feb 2003 19:55:35 -0000 1.9 *************** *** 7,11 **** import os import sys ! import regex import getopt --- 7,11 ---- import os import sys ! import re import getopt *************** *** 14,19 **** opts, args = getopt.getopt(sys.argv[1:], '') if len(args) < 2: ! raise getopt.error, 'not enough arguments' ! except getopt.error, msg: sys.stdout = sys.stderr print msg --- 14,19 ---- opts, args = getopt.getopt(sys.argv[1:], '') if len(args) < 2: ! raise getopt.GetoptError('not enough arguments', None) ! except getopt.GetoptError, msg: sys.stdout = sys.stderr print msg *************** *** 21,25 **** sys.exit(2) pat, dirs = args[0], args[1:] ! prog = regex.compile(pat) for dirname in dirs: os.path.walk(dirname, visit, prog) --- 21,25 ---- sys.exit(2) pat, dirs = args[0], args[1:] ! prog = re.compile(pat) for dirname in dirs: os.path.walk(dirname, visit, prog) *************** *** 35,39 **** try: linkto = os.readlink(name) ! if prog.search(linkto) >= 0: print name, '->', linkto except os.error: --- 35,39 ---- try: linkto = os.readlink(name) ! if prog.search(linkto) is not None: print name, '->', linkto except os.error: From tim_one@users.sourceforge.net Thu Feb 6 20:29:24 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 06 Feb 2003 12:29:24 -0800 Subject: [Python-checkins] python/nondist/peps pep-0307.txt,1.11,1.12 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv3118 Modified Files: pep-0307.txt Log Message: Quick checkin to make sure I still have the mechanics straight in this directory. Index: pep-0307.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0307.txt,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** pep-0307.txt 4 Feb 2003 19:28:16 -0000 1.11 --- pep-0307.txt 6 Feb 2003 20:29:21 -0000 1.12 *************** *** 37,43 **** Pickling new-style objects causes serious pickle bloat. For ! example, the binary pickle for a classic object with one instance ! variable takes up 33 bytes; a new-style object with one instance ! variable takes up 86 bytes. This was measured as follows: class C(object): # Omit "(object)" for classic class --- 37,41 ---- Pickling new-style objects causes serious pickle bloat. For ! example, class C(object): # Omit "(object)" for classic class *************** *** 46,49 **** --- 44,50 ---- x.foo = 42 print len(pickle.dumps(x, 1)) + + The binary pickle for the classic object consumed 33 bytes, and for + the new-style object 86 bytes. The reasons for the bloat are complex, but are mostly caused by From tim_one@users.sourceforge.net Thu Feb 6 20:35:03 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 06 Feb 2003 12:35:03 -0800 Subject: [Python-checkins] python/nondist/peps pep-0307.txt,1.12,1.13 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv6890 Modified Files: pep-0307.txt Log Message: Minor edits to the "Protocol versions" section. Index: pep-0307.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0307.txt,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** pep-0307.txt 6 Feb 2003 20:29:21 -0000 1.12 --- pep-0307.txt 6 Feb 2003 20:35:00 -0000 1.13 *************** *** 60,86 **** Protocol versions ! Previously, pickling (but not unpickling) has distinguished ! between text mode and binary mode. By design, text mode is a ! subset of binary mode, and unpicklers don't need to know in advance whether an incoming pickle uses text mode or binary mode. The virtual machine used for unpickling is the same regardless of ! the mode; certain opcode simply aren't used in text mode. ! Retroactively, text mode is called protocol 0, and binary mode is ! called protocol 1. The new protocol is called protocol 2. In the tradition of pickling protocols, protocol 2 is a superset of protocol 1. But just so that future pickling protocols aren't required to be supersets of the oldest protocols, a new opcode is inserted at the start of a protocol 2 pickle indicating that it is ! using protocol 2. Several functions, methods and constructors used for pickling used to take a positional argument named 'bin' which was a flag, defaulting to 0, indicating binary mode. This argument is renamed ! to 'proto' and now gives the protocol number, defaulting to 0. It so happens that passing 2 for the 'bin' argument in previous Python versions had the same effect as passing 1. Nevertheless, a ! special case is added here: passing a negative number selects the highest protocol version supported by a particular implementation. This works in previous Python versions, too. --- 60,89 ---- Protocol versions ! Previously, pickling (but not unpickling) distinguished between ! text mode and binary mode. By design, binary mode is a ! superset of text mode, and unpicklers don't need to know in advance whether an incoming pickle uses text mode or binary mode. The virtual machine used for unpickling is the same regardless of ! the mode; certain opcodes simply aren't used in text mode. ! Retroactively, text mode is now called protocol 0, and binary mode ! protocol 1. The new protocol is called protocol 2. In the tradition of pickling protocols, protocol 2 is a superset of protocol 1. But just so that future pickling protocols aren't required to be supersets of the oldest protocols, a new opcode is inserted at the start of a protocol 2 pickle indicating that it is ! using protocol 2. To date, each release of Python has been able to ! read pickles written by all previous releases. Of course pickles ! written under protocol N can't be read by versions of Python ! earlier than the one that introduced protocol N. Several functions, methods and constructors used for pickling used to take a positional argument named 'bin' which was a flag, defaulting to 0, indicating binary mode. This argument is renamed ! to 'proto' and now gives the protocol number, still defaulting to 0. It so happens that passing 2 for the 'bin' argument in previous Python versions had the same effect as passing 1. Nevertheless, a ! special case is added here: passing a negative number selects the highest protocol version supported by a particular implementation. This works in previous Python versions, too. From tim_one@users.sourceforge.net Thu Feb 6 20:38:34 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 06 Feb 2003 12:38:34 -0800 Subject: [Python-checkins] python/nondist/peps pep-0307.txt,1.13,1.14 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv8818 Modified Files: pep-0307.txt Log Message: Intro: make explicit that the new protocol is to be introduced with 2.3. Index: pep-0307.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0307.txt,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** pep-0307.txt 6 Feb 2003 20:35:00 -0000 1.13 --- pep-0307.txt 6 Feb 2003 20:38:30 -0000 1.14 *************** *** 15,20 **** Pickling new-style objects in Python 2.2 is done somewhat clumsily and causes pickle size to bloat compared to classic class ! instances. This PEP documents a new pickle protocol that takes ! care of this and many other pickle issues. There are two sides to specifying a new pickle protocol: the byte --- 15,20 ---- Pickling new-style objects in Python 2.2 is done somewhat clumsily and causes pickle size to bloat compared to classic class ! instances. This PEP documents a new pickle protocol in Python 2.3 ! that takes care of this and many other pickle issues. There are two sides to specifying a new pickle protocol: the byte From neal@metaslash.com Thu Feb 6 21:21:13 2003 From: neal@metaslash.com (Neal Norwitz) Date: Thu, 06 Feb 2003 16:21:13 -0500 Subject: [Python-checkins] python/dist/src/Python ceval.c,2.347,2.348 compile.c,2.272,2.273 sysmodule.c,2.112,2.113 In-Reply-To: References: Message-ID: <20030206212113.GD23059@epoch.metaslash.com> > + #ifdef CALL_PROFILE > + #define PCALL_NUM 11 > + #define PCALL_POP 10 > + PyObject * > + PyEval_GetCallStats(PyObject *self) > + { > + return Py_BuildValue("iiiiiiiiii", > + pcall[0], pcall[1], pcall[2], pcall[3], > + pcall[4], pcall[5], pcall[6], pcall[7], > + pcall[8], pcall[9]); > + } Shouldn't there be another i and pcall[10]? sysmodule also documented 11 calls. Neal From gvanrossum@users.sourceforge.net Thu Feb 6 21:25:17 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 06 Feb 2003 13:25:17 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_copy.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv1908/test Modified Files: test_copy.py Log Message: Fix a bug in the way __getnewargs__ was handled. Index: test_copy.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_copy.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_copy.py 6 Feb 2003 19:53:22 -0000 1.3 --- test_copy.py 6 Feb 2003 21:25:12 -0000 1.4 *************** *** 455,458 **** --- 455,476 ---- self.assert_(x.foo is not y.foo) + def test_copy_tuple_subclass(self): + class C(tuple): + pass + x = C([1, 2, 3]) + self.assertEqual(tuple(x), (1, 2, 3)) + y = copy.copy(x) + self.assertEqual(tuple(y), (1, 2, 3)) + + def test_deepcopy_tuple_subclass(self): + class C(tuple): + pass + x = C([[1, 2], 3]) + self.assertEqual(tuple(x), ([1, 2], 3)) + y = copy.deepcopy(x) + self.assertEqual(tuple(y), ([1, 2], 3)) + self.assert_(x is not y) + self.assert_(x[0] is not y[0]) + def test_main(): suite = unittest.TestSuite() From gvanrossum@users.sourceforge.net Thu Feb 6 21:25:44 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 06 Feb 2003 13:25:44 -0800 Subject: [Python-checkins] python/dist/src/Lib copy.py,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv1908 Modified Files: copy.py Log Message: Fix a bug in the way __getnewargs__ was handled. Index: copy.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** copy.py 6 Feb 2003 19:53:22 -0000 1.32 --- copy.py 6 Feb 2003 21:25:08 -0000 1.33 *************** *** 129,133 **** elif isinstance(obj, dict): dictitems = obj.iteritems() ! return __newobj__, (cls, args), state, listitems, dictitems --- 129,133 ---- elif isinstance(obj, dict): dictitems = obj.iteritems() ! return __newobj__, (cls,) + args, state, listitems, dictitems From fdrake@users.sourceforge.net Thu Feb 6 22:11:04 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Thu, 06 Feb 2003 14:11:04 -0800 Subject: [Python-checkins] python/nondist/peps pep-0042.txt,1.68,1.69 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv29446 Modified Files: pep-0042.txt Log Message: Fix typo. Index: pep-0042.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0042.txt,v retrieving revision 1.68 retrieving revision 1.69 diff -C2 -d -r1.68 -r1.69 *** pep-0042.txt 6 Feb 2003 17:57:14 -0000 1.68 --- pep-0042.txt 6 Feb 2003 22:11:01 -0000 1.69 *************** *** 171,175 **** - urlparse should be updated to comply with RFC 2396, which ! defines optional parameters for each segment of the page. http://www.python.org/sf/210834 --- 171,175 ---- - urlparse should be updated to comply with RFC 2396, which ! defines optional parameters for each segment of the path. http://www.python.org/sf/210834 From jackjansen@users.sourceforge.net Thu Feb 6 22:32:41 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 06 Feb 2003 14:32:41 -0800 Subject: [Python-checkins] python/dist/src/Mac/Tools/IDE MacPrefs.py,1.5,1.6 ProfileBrowser.py,1.4,1.5 PyBrowser.py,1.21,1.22 PyConsole.py,1.14,1.15 PyDocSearch.py,1.10,1.11 PyEdit.py,1.34,1.35 PythonIDEMain.py,1.26,1.27 Wapplication.py,1.20,1.21 Wquicktime.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory sc8-pr-cvs1:/tmp/cvs-serv8695 Modified Files: MacPrefs.py ProfileBrowser.py PyBrowser.py PyConsole.py PyDocSearch.py PyEdit.py PythonIDEMain.py Wapplication.py Wquicktime.py Log Message: Got rid of macfs and FSSpecs in general (pathnames or FSRefs are now used everywhere). Index: MacPrefs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/MacPrefs.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** MacPrefs.py 13 Dec 2002 23:32:51 -0000 1.5 --- MacPrefs.py 6 Feb 2003 22:32:35 -0000 1.6 *************** *** 1,7 **** - import macfs import marshal import types ! ! from MACFS import kOnSystemDisk class PrefObject: --- 1,6 ---- import marshal import types ! from Carbon import Folder ! from Carbon import Folders class PrefObject: *************** *** 72,77 **** marshal.dump(prefdict, open(self.__path, 'wb')) try: ! fss = macfs.FSSpec(macfs.FSRef(self.__path)) ! fss.SetCreatorType(self.__creator, 'pref') except: pass --- 71,75 ---- marshal.dump(prefdict, open(self.__path, 'wb')) try: ! MacOS.SetCreatorAndType(self.__path, self.__creator, 'pref') except: pass *************** *** 99,105 **** return _prefscache[prefname] # Find the preferences folder and our prefs file, create if needed. ! vrefnum, dirid = macfs.FindFolder(kOnSystemDisk, 'pref', 0) ! prefsfolder_fss = macfs.FSSpec((vrefnum, dirid, '')) ! prefsfolder = macfs.FSRef(prefsfolder_fss).as_fsspec().as_pathname() path = os.path.join(prefsfolder, prefname) head, tail = os.path.split(path) --- 97,102 ---- return _prefscache[prefname] # Find the preferences folder and our prefs file, create if needed. ! fsr = Folder.FSFindFolder(Folders.kOnSystemDisk, 'pref', 1) ! prefsfolder = fsr.as_pathname() path = os.path.join(prefsfolder, prefname) head, tail = os.path.split(path) Index: ProfileBrowser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/ProfileBrowser.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** ProfileBrowser.py 26 Jan 2003 22:15:48 -0000 1.4 --- ProfileBrowser.py 6 Feb 2003 22:32:35 -0000 1.5 *************** *** 84,88 **** browser = ProfileBrowser(stats) else: - import macfs filename = EasyDialogs.AskFileForOpen(message='Profiler data') if not filename: sys.exit(0) --- 84,87 ---- Index: PyBrowser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyBrowser.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** PyBrowser.py 13 Dec 2002 15:14:22 -0000 1.21 --- PyBrowser.py 6 Feb 2003 22:32:35 -0000 1.22 *************** *** 323,329 **** return elif os.path.exists(value) and os.path.isfile(value): ! import macfs ! fss = macfs.FSSpec(value) ! if fss.GetCreatorType()[1] == 'TEXT': W.getapplication().openscript(value) --- 323,327 ---- return elif os.path.exists(value) and os.path.isfile(value): ! if MacOS.GetCreatorAndType(value)[1] in ('TEXT', '\0\0\0\0'): W.getapplication().openscript(value) Index: PyConsole.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyConsole.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** PyConsole.py 26 Jan 2003 22:15:48 -0000 1.14 --- PyConsole.py 6 Feb 2003 22:32:35 -0000 1.15 *************** *** 86,90 **** def domenu_save_as(self, *args): - import macfs filename = EasyDialogs.AskFileForSave(message='Save console text as:', savedFileName='console.txt') --- 86,89 ---- *************** *** 94,98 **** f.write(self.get()) f.close() ! fss.SetCreatorType(W._signature, 'TEXT') def write(self, text): --- 93,97 ---- f.write(self.get()) f.close() ! MacOS.SetCreatorAndType(filename, W._signature, 'TEXT') def write(self, text): *************** *** 243,247 **** def domenu_save_as(self, *args): title = self._parentwindow.gettitle() - import macfs filename = EasyDialogs.AskFileForSave(message='Save %s text as:' % title, savedFileName=title + '.txt') --- 242,245 ---- *************** *** 251,255 **** f.write(self.get()) f.close() ! fss.SetCreatorType(W._signature, 'TEXT') def domenu_cut(self, *args): --- 249,253 ---- f.write(self.get()) f.close() ! MacOS.SetCreatorAndType(filename, W._signature, 'TEXT') def domenu_cut(self, *args): Index: PyDocSearch.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyDocSearch.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** PyDocSearch.py 26 Jan 2003 22:15:48 -0000 1.10 --- PyDocSearch.py 6 Feb 2003 22:32:35 -0000 1.11 *************** *** 1,5 **** import re import W - import macfs import os import MacPrefs --- 1,4 ---- Index: PyEdit.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyEdit.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** PyEdit.py 26 Jan 2003 22:15:48 -0000 1.34 --- PyEdit.py 6 Feb 2003 22:32:35 -0000 1.35 *************** *** 5,10 **** from Wkeys import * - import macfs - import MACFS import MacOS import EasyDialogs --- 5,8 ---- *************** *** 13,16 **** --- 11,15 ---- from Carbon import Evt from Carbon import Qd + from Carbon import File import os import imp *************** *** 20,23 **** --- 19,24 ---- import re + smAllScripts = -3 + if hasattr(Win, "FrontNonFloatingWindow"): MyFrontWindow = Win.FrontNonFloatingWindow *************** *** 62,67 **** text = f.read() f.close() ! fss = macfs.FSSpec(path) ! self._creator, filetype = fss.GetCreatorType() else: raise IOError, "file '%s' does not exist" % path --- 63,67 ---- text = f.read() f.close() ! self._creator, filetype = MacOS.GetCreatorAndType(path) else: raise IOError, "file '%s' does not exist" % path *************** *** 135,139 **** resref = Res.FSpOpenResFile(self.path, 3) except Res.Error: ! Res.FSpCreateResFile(self.path, self._creator, 'TEXT', MACFS.smAllScripts) resref = Res.FSpOpenResFile(self.path, 3) try: --- 135,139 ---- resref = Res.FSpOpenResFile(self.path, 3) except Res.Error: ! Res.FSpCreateResFile(self.path, self._creator, 'TEXT', smAllScripts) resref = Res.FSpOpenResFile(self.path, 3) try: *************** *** 390,395 **** fp.write(data) fp.close() ! fss = macfs.FSSpec(self.path) ! fss.SetCreatorType(self._creator, 'TEXT') self.getsettings() self.writewindowsettings() --- 390,394 ---- fp.write(data) fp.close() ! MacOS.SetCreatorAndType(self.path, self._creator, 'TEXT') self.getsettings() self.writewindowsettings() *************** *** 420,425 **** if hasattr(app, 'makescriptsmenu'): app = W.getapplication() ! fss, fss_changed = app.scriptsfolder.Resolve() ! path = fss.as_pathname() if path == self.path[:len(path)]: W.getapplication().makescriptsmenu() --- 419,424 ---- if hasattr(app, 'makescriptsmenu'): app = W.getapplication() ! fsr, changed = app.scriptsfolder.FSResolveAlias(None) ! path = fsr.as_pathname() if path == self.path[:len(path)]: W.getapplication().makescriptsmenu() *************** *** 547,558 **** file_path = self.path if not os.path.exists(interp_path): ! # This "can happen" if we are running IDE under MacPython. Try ! # the standard location. ! interp_path = "/Library/Frameworks/Python.framework/Versions/2.3/bin/python" ! try: ! fsr = macfs.FSRef(interp_path) ! except macfs.Error: ! raise W.AlertError, "Can't find command-line Python" ! file_path = macfs.FSRef(macfs.FSSpec(self.path)).as_pathname() cmd = '"%s" "%s" ; exit' % (interp_path, file_path) t = Terminal.Terminal() --- 546,551 ---- file_path = self.path if not os.path.exists(interp_path): ! # This "can happen" if we are running IDE under MacPython-OS9. ! raise W.AlertError, "Can't find command-line Python" cmd = '"%s" "%s" ; exit' % (interp_path, file_path) t = Terminal.Terminal() *************** *** 1369,1374 **** def resolvealiases(path): try: ! return macfs.ResolveAliasFile(path)[0].as_pathname() ! except (macfs.error, ValueError), (error, str): if error <> -120: raise --- 1362,1369 ---- def resolvealiases(path): try: ! fsr, d1, d2 = File.FSResolveAliasFile(path, 1) ! path = fsr.as_pathname() ! return path ! except (File.Error, ValueError), (error, str): if error <> -120: raise Index: PythonIDEMain.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PythonIDEMain.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** PythonIDEMain.py 5 Feb 2003 15:41:09 -0000 1.26 --- PythonIDEMain.py 6 Feb 2003 22:32:35 -0000 1.27 *************** *** 8,14 **** import os import sys - import macfs import MacOS import EasyDialogs if MacOS.runtimemodel == 'macho': --- 8,15 ---- import os import sys import MacOS import EasyDialogs + from Carbon import File + from Carbon import Files if MacOS.runtimemodel == 'macho': *************** *** 24,27 **** --- 25,32 ---- return not not value + def getmodtime(file): + file = File.FSRef(file) + catinfo, d1, d2, d3 = file.FSGetCatalogInfo(Files.kFSCatInfoContentMod) + return catinfo.contentModDate class PythonIDE(Wapplication.Application): *************** *** 126,133 **** prefs = self.getprefs() try: ! fss, fss_changed = macfs.RawAlias(prefs.scriptsfolder).Resolve() ! self.scriptsfolder = fss.NewAlias() except: ! path = os.path.join(os.getcwd(), ":Mac:IDE scripts") if not os.path.exists(path): path = os.path.join(os.getcwd(), "Scripts") --- 131,138 ---- prefs = self.getprefs() try: ! fsr, d = File.Alias(rawdata=prefs.scriptsfolder).FSResolveAlias(None) ! self.scriptsfolder = fsr.FSNewAliasMinimal() except: ! path = os.path.join(os.getcwd(), "Mac", "IDE scripts") if not os.path.exists(path): path = os.path.join(os.getcwd(), "Scripts") *************** *** 136,144 **** f = open(os.path.join(path, "Place your scripts here"+ELIPSES), "w") f.close() ! fss = macfs.FSSpec(path) ! self.scriptsfolder = fss.NewAlias() ! self.scriptsfoldermodtime = fss.GetDates()[1] else: ! self.scriptsfoldermodtime = fss.GetDates()[1] prefs.scriptsfolder = self.scriptsfolder.data self._scripts = {} --- 141,149 ---- f = open(os.path.join(path, "Place your scripts here"+ELIPSES), "w") f.close() ! fsr = File.FSRef(path) ! self.scriptsfolder = fsr.FSNewAliasMinimal() ! self.scriptsfoldermodtime = getmodtime(fsr) else: ! self.scriptsfoldermodtime = getmodtime(fsr) prefs.scriptsfolder = self.scriptsfolder.data self._scripts = {} *************** *** 154,160 **** def suspendresume(self, onoff): if onoff: ! fss, fss_changed = self.scriptsfolder.Resolve() ! modtime = fss.GetDates()[1] ! if self.scriptsfoldermodtime <> modtime or fss_changed: self.scriptsfoldermodtime = modtime W.SetCursor('watch') --- 159,165 ---- def suspendresume(self, onoff): if onoff: ! fsr, changed = self.scriptsfolder.FSResolveAlias(None) ! modtime = getmodtime(fsr) ! if self.scriptsfoldermodtime <> modtime or changed: self.scriptsfoldermodtime = modtime W.SetCursor('watch') *************** *** 172,181 **** docs = [docs] for doc in docs: ! fss, a = doc.Resolve() ! path = fss.as_pathname() self.opendoc(path) def opendoc(self, path): ! fcreator, ftype = macfs.FSSpec(path).GetCreatorType() if ftype == 'TEXT': self.openscript(path) --- 177,186 ---- docs = [docs] for doc in docs: ! fsr, a = doc.FSResolveAlias(None) ! path = fsr.as_pathname() self.opendoc(path) def opendoc(self, path): ! fcreator, ftype = MacOS.GetCreatorAndType(path) if ftype == 'TEXT': self.openscript(path) *************** *** 192,200 **** def do_setscriptsfolder(self, *args): ! fss = EasyDialogs.AskFolder(message="Select Scripts Folder", ! wanted=macfs.FSSpec) ! if fss: prefs = self.getprefs() ! alis = fss.NewAlias() prefs.scriptsfolder = alis.data self.scriptsfolder = alis --- 197,205 ---- def do_setscriptsfolder(self, *args): ! fsr = EasyDialogs.AskFolder(message="Select Scripts Folder", ! wanted=File.FSRef) ! if fsr: prefs = self.getprefs() ! alis = fsr.FSNewAliasMinimal() prefs.scriptsfolder = alis.data self.scriptsfolder = alis *************** *** 247,252 **** #FrameWork.MenuItem(self.scriptsmenu, "New script", None, self.domenu_new) #self.scriptsmenu.addseparator() ! fss, fss_changed = self.scriptsfolder.Resolve() ! self.scriptswalk(fss.as_pathname(), self.scriptsmenu) def makeopenwindowsmenu(self): --- 252,257 ---- #FrameWork.MenuItem(self.scriptsmenu, "New script", None, self.domenu_new) #self.scriptsmenu.addseparator() ! fsr, d1 = self.scriptsfolder.FSResolveAlias(None) ! self.scriptswalk(fsr.as_pathname(), self.scriptsmenu) def makeopenwindowsmenu(self): Index: Wapplication.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/Wapplication.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** Wapplication.py 9 Jan 2003 23:20:31 -0000 1.20 --- Wapplication.py 6 Feb 2003 22:32:35 -0000 1.21 *************** *** 9,12 **** --- 9,13 ---- from Carbon import Menu; MenuToolbox = Menu; del Menu import macresource + from Carbon import File if hasattr(Win, "FrontNonFloatingWindow"): *************** *** 274,278 **** return done[top] = 1 ! import os, macfs, string try: names = os.listdir(top) --- 275,279 ---- return done[top] = 1 ! import os, string try: names = os.listdir(top) *************** *** 286,294 **** continue try: ! fss, isdir, isalias = macfs.ResolveAliasFile(name) except: # maybe a broken alias continue ! path = fss.as_pathname() if done.has_key(path): continue --- 287,295 ---- continue try: ! fsr, isdir, isalias = File.FSResolveAliasFile(name, 1) except: # maybe a broken alias continue ! path = fsr.as_pathname() if done.has_key(path): continue *************** *** 302,306 **** self.scriptswalk(path, submenu, done) else: ! creator, type = fss.GetCreatorType() if type == 'TEXT': if name[-3:] == '.py': --- 303,307 ---- self.scriptswalk(path, submenu, done) else: ! creator, type = MacOS.GetCreatorAndType(path) if type == 'TEXT': if name[-3:] == '.py': Index: Wquicktime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/Wquicktime.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Wquicktime.py 25 Aug 2001 12:14:38 -0000 1.4 --- Wquicktime.py 6 Feb 2003 22:32:35 -0000 1.5 *************** *** 4,8 **** from Carbon import Qt, QuickTime import W ! import macfs from Carbon import Evt, Events --- 4,8 ---- from Carbon import Qt, QuickTime import W ! from Carbon import File from Carbon import Evt, Events *************** *** 34,45 **** #self.GetWindow().InvalWindowRect(self.movie.GetMovieBox()) Qd.PaintRect(self.movie.GetMovieBox()) ! if type(path_or_fss) == type(''): ! path = path_or_fss ! fss = macfs.FSSpec(path) ! else: ! path = path_or_fss.as_pathname() ! fss = path_or_fss self.movietitle = os.path.basename(path) ! movieResRef = Qt.OpenMovieFile(fss, 1) self.movie, dummy, dummy = Qt.NewMovieFromFile(movieResRef, 0, QuickTime.newMovieActive) self.moviebox = self.movie.GetMovieBox() --- 34,40 ---- #self.GetWindow().InvalWindowRect(self.movie.GetMovieBox()) Qd.PaintRect(self.movie.GetMovieBox()) ! path = File.pathname(path) self.movietitle = os.path.basename(path) ! movieResRef = Qt.OpenMovieFile(path_or_fss, 1) self.movie, dummy, dummy = Qt.NewMovieFromFile(movieResRef, 0, QuickTime.newMovieActive) self.moviebox = self.movie.GetMovieBox() From jackjansen@users.sourceforge.net Thu Feb 6 22:57:47 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 06 Feb 2003 14:57:47 -0800 Subject: [Python-checkins] python/dist/src/Mac/scripts mkestrres.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv21528 Modified Files: mkestrres.py Log Message: Got rid of FSSpecs. Index: mkestrres.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/mkestrres.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** mkestrres.py 22 Apr 2002 11:44:26 -0000 1.9 --- mkestrres.py 6 Feb 2003 22:57:44 -0000 1.10 *************** *** 2,6 **** import re - import macfs import string from Carbon import Res --- 2,5 ---- *************** *** 106,150 **** def main(): dict = {} ! fss, ok = macfs.PromptGetFile("Where is GUSI sys/errno.h?") ! if not ok: return ! fp = open(fss.as_pathname()) ! parse_errno_h(fp, dict) ! fp.close() ! fss, ok = macfs.PromptGetFile("Select cerrno (MSL) or cancel") ! if not ok: return ! fp = open(fss.as_pathname()) ! parse_errno_h(fp, dict) ! fp.close() ! fss, ok = macfs.PromptGetFile("Where is MacErrors.h?") ! if not ok: return ! fp = open(fss.as_pathname()) ! parse_errors_h(fp, dict) ! fp.close() ! fss, ok = macfs.PromptGetFile("Where is mkestrres-MacErrors.h?") ! if not ok: return ! fp = open(fss.as_pathname()) ! parse_errors_h(fp, dict) ! fp.close() if not dict: return ! fss, ok = macfs.StandardPutFile("Resource output file?", "errors.rsrc") ! if ok: writeestr(fss, dict) ! fss, ok = macfs.StandardPutFile("Python output file?", "macerrors.py") ! if ok: ! fp = open(fss.as_pathname(), "w") writepython(fp, dict) fp.close() fss.SetCreatorType('Pyth', 'TEXT') ! fss, ok = macfs.StandardPutFile("Text output file?", "errors.txt") ! if ok: ! fp = open(fss.as_pathname(), "w") k = dict.keys() --- 105,149 ---- def main(): dict = {} ! pathname = EasyDialogs.AskFileForOpen(message="Where is GUSI sys/errno.h?") ! if pathname: ! fp = open(pathname) ! parse_errno_h(fp, dict) ! fp.close() ! pathname = EasyDialogs.AskFileForOpen(message="Select cerrno (MSL) or cancel") ! if pathname: ! fp = open(pathname) ! parse_errno_h(fp, dict) ! fp.close() ! pathname = EasyDialogs.AskFileForOpen(message="Where is MacErrors.h?") ! if pathname: ! fp = open(pathname) ! parse_errors_h(fp, dict) ! fp.close() ! pathname = EasyDialogs.AskFileForOpen(message="Where is mkestrres-MacErrors.h?") ! if pathname: ! fp = open(pathname) ! parse_errors_h(fp, dict) ! fp.close() if not dict: return ! pathname = EasyDialogs.AskFileForSave(message="Resource output file?", savedFileName="errors.rsrc") ! if pathname: writeestr(fss, dict) ! pathname = EasyDialogs.AskFileForSave(message="Python output file?", savedFileName="macerrors.py") ! if pathname: ! fp = open(pathname, "w") writepython(fp, dict) fp.close() fss.SetCreatorType('Pyth', 'TEXT') ! pathname = EasyDialogs.AskFileForSave(message="Text output file?", savedFileName="errors.txt") ! if pathname: ! fp = open(pathname, "w") k = dict.keys() From gvanrossum@users.sourceforge.net Thu Feb 6 22:57:02 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 06 Feb 2003 14:57:02 -0800 Subject: [Python-checkins] python/dist/src/Lib copy.py,1.33,1.34 copy_reg.py,1.16,1.17 pickle.py,1.147,1.148 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv20624 Modified Files: copy.py copy_reg.py pickle.py Log Message: Move _better_reduce from copy.py to copy_reg.py, and also use it in pickle.py, where it makes save_newobj() unnecessary. Tests pass. Index: copy.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** copy.py 6 Feb 2003 21:25:08 -0000 1.33 --- copy.py 6 Feb 2003 22:57:00 -0000 1.34 *************** *** 52,56 **** import types ! from pickle import _slotnames class Error(Exception): --- 52,56 ---- import types ! from copy_reg import _better_reduce class Error(Exception): *************** *** 90,133 **** y = copierfunction(x) return y - - def __newobj__(cls, *args): - return cls.__new__(cls, *args) - - def _better_reduce(obj): - cls = obj.__class__ - getnewargs = getattr(obj, "__getnewargs__", None) - if getnewargs: - args = getnewargs() - else: - args = () - getstate = getattr(obj, "__getstate__", None) - if getstate: - try: - state = getstate() - except TypeError, err: - # XXX Catch generic exception caused by __slots__ - if str(err) != ("a class that defines __slots__ " - "without defining __getstate__ " - "cannot be pickled"): - raise # Not that specific exception - getstate = None - if not getstate: - state = getattr(obj, "__dict__", None) - names = _slotnames(cls) - if names: - slots = {} - nil = [] - for name in names: - value = getattr(obj, name, nil) - if value is not nil: - slots[name] = value - if slots: - state = (state, slots) - listitems = dictitems = None - if isinstance(obj, list): - listitems = iter(obj) - elif isinstance(obj, dict): - dictitems = obj.iteritems() - return __newobj__, (cls,) + args, state, listitems, dictitems --- 90,93 ---- Index: copy_reg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy_reg.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** copy_reg.py 4 Feb 2003 05:06:17 -0000 1.16 --- copy_reg.py 6 Feb 2003 22:57:00 -0000 1.17 *************** *** 70,73 **** --- 70,151 ---- return _reconstructor, args + # A better version of _reduce, used by copy and pickle protocol 2 + + def __newobj__(cls, *args): + return cls.__new__(cls, *args) + + def _better_reduce(obj): + cls = obj.__class__ + getnewargs = getattr(obj, "__getnewargs__", None) + if getnewargs: + args = getnewargs() + else: + args = () + getstate = getattr(obj, "__getstate__", None) + if getstate: + try: + state = getstate() + except TypeError, err: + # XXX Catch generic exception caused by __slots__ + if str(err) != ("a class that defines __slots__ " + "without defining __getstate__ " + "cannot be pickled"): + raise # Not that specific exception + getstate = None + if not getstate: + state = getattr(obj, "__dict__", None) + names = _slotnames(cls) + if names: + slots = {} + nil = [] + for name in names: + value = getattr(obj, name, nil) + if value is not nil: + slots[name] = value + if slots: + state = (state, slots) + listitems = dictitems = None + if isinstance(obj, list): + listitems = iter(obj) + elif isinstance(obj, dict): + dictitems = obj.iteritems() + return __newobj__, (cls,) + args, state, listitems, dictitems + + def _slotnames(cls): + """Return a list of slot names for a given class. + + This needs to find slots defined by the class and its bases, so we + can't simply return the __slots__ attribute. We must walk down + the Method Resolution Order and concatenate the __slots__ of each + class found there. (This assumes classes don't modify their + __slots__ attribute to misrepresent their slots after the class is + defined.) + """ + + # Get the value from a cache in the class if possible + names = cls.__dict__.get("__slotnames__") + if names is not None: + return names + + # Not cached -- calculate the value + names = [] + if not hasattr(cls, "__slots__"): + # This class has no slots + pass + else: + # Slots found -- gather slot names from all base classes + for c in cls.__mro__: + if "__slots__" in c.__dict__: + names += [name for name in c.__dict__["__slots__"] + if name not in ("__dict__", "__weakref__")] + + # Cache the outcome in the class if at all possible + try: + cls.__slotnames__ = names + except: + pass # But don't die if we can't + + return names + # A registry of extension codes. This is an ad-hoc compression # mechanism. Whenever a global reference to , is about Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.147 retrieving revision 1.148 diff -C2 -d -r1.147 -r1.148 *** pickle.py 6 Feb 2003 19:30:38 -0000 1.147 --- pickle.py 6 Feb 2003 22:57:00 -0000 1.148 *************** *** 28,32 **** from types import * ! from copy_reg import dispatch_table, _reconstructor from copy_reg import _extension_registry, _inverted_registry, _extension_cache import marshal --- 28,32 ---- from types import * ! from copy_reg import dispatch_table, _reconstructor, _better_reduce from copy_reg import _extension_registry, _inverted_registry, _extension_cache import marshal *************** *** 311,318 **** # Protocol 2 can do better than the default __reduce__ if reduce is object.__reduce__: ! reduce = None ! if not reduce: ! self.save_newobj(obj) ! return if not reduce: raise PicklingError("Can't pickle %r object: %r" % --- 311,315 ---- # Protocol 2 can do better than the default __reduce__ if reduce is object.__reduce__: ! reduce = _better_reduce if not reduce: raise PicklingError("Can't pickle %r object: %r" % *************** *** 434,517 **** write(BUILD) - def save_newobj(self, obj): - # Save a new-style class instance, using protocol 2. - assert self.proto >= 2 # This only works for protocol 2 - t = type(obj) - getnewargs = getattr(obj, "__getnewargs__", None) - if getnewargs: - args = getnewargs() # This better not reference obj - else: - args = () - - save = self.save - write = self.write - - self.save(t) - save(args) - write(NEWOBJ) - self.memoize(obj) - - if isinstance(obj, list): - self._batch_appends(iter(obj)) - elif isinstance(obj, dict): - self._batch_setitems(obj.iteritems()) - - getstate = getattr(obj, "__getstate__", None) - - if getstate: - # A class may define both __getstate__ and __getnewargs__. - # If they are the same function, we ignore __getstate__. - # This is for the benefit of protocols 0 and 1, which don't - # use __getnewargs__. Note that the only way to make them - # the same function is something like this: - # - # class C(object): - # def __getstate__(self): - # return ... - # __getnewargs__ = __getstate__ - # - # No tricks are needed to ignore __setstate__; it simply - # won't be called when we don't generate BUILD. - # Also note that when __getnewargs__ and __getstate__ are - # the same function, we don't do the default thing of - # looking for __dict__ and slots either -- it is assumed - # that __getnewargs__ returns all the state there is - # (which should be a safe assumption since __getstate__ - # returns the *same* state). - if getstate == getnewargs: - return - - try: - state = getstate() - except TypeError, err: - # XXX Catch generic exception caused by __slots__ - if str(err) != ("a class that defines __slots__ " - "without defining __getstate__ " - "cannot be pickled"): - raise # Not that specific exception - getstate = None - - if not getstate: - state = getattr(obj, "__dict__", None) - if not state: - state = None - # If there are slots, the state becomes a tuple of two - # items: the first item the regular __dict__ or None, and - # the second a dict mapping slot names to slot values - names = _slotnames(t) - if names: - slots = {} - nil = [] - for name in names: - value = getattr(obj, name, nil) - if value is not nil: - slots[name] = value - if slots: - state = (state, slots) - - if state is not None: - save(state) - write(BUILD) - # Methods below this point are dispatched through the dispatch table --- 431,434 ---- *************** *** 714,718 **** for i in r: try: ! tmp.append(items.next()) except StopIteration: items = None --- 631,636 ---- for i in r: try: ! x = items.next() ! tmp.append(x) except StopIteration: items = None *************** *** 865,904 **** # Pickling helpers - - def _slotnames(cls): - """Return a list of slot names for a given class. - - This needs to find slots defined by the class and its bases, so we - can't simply return the __slots__ attribute. We must walk down - the Method Resolution Order and concatenate the __slots__ of each - class found there. (This assumes classes don't modify their - __slots__ attribute to misrepresent their slots after the class is - defined.) - """ - - # Get the value from a cache in the class if possible - names = cls.__dict__.get("__slotnames__") - if names is not None: - return names - - # Not cached -- calculate the value - names = [] - if not hasattr(cls, "__slots__"): - # This class has no slots - pass - else: - # Slots found -- gather slot names from all base classes - for c in cls.__mro__: - if "__slots__" in c.__dict__: - names += [name for name in c.__dict__["__slots__"] - if name not in ("__dict__", "__weakref__")] - - # Cache the outcome in the class if at all possible - try: - cls.__slotnames__ = names - except: - pass # But don't die if we can't - - return names def _keep_alive(x, memo): --- 783,786 ---- From jackjansen@users.sourceforge.net Thu Feb 6 23:10:48 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 06 Feb 2003 15:10:48 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.644,1.645 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv28023 Modified Files: NEWS Log Message: Added a note about getting rid of macfs usage (MacPython). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.644 retrieving revision 1.645 diff -C2 -d -r1.644 -r1.645 *** NEWS 6 Feb 2003 16:16:50 -0000 1.644 --- NEWS 6 Feb 2003 23:10:45 -0000 1.645 *************** *** 272,275 **** --- 272,279 ---- - There are new dialogs EasyDialogs.AskFileForOpen, AskFileForSave and AskFolder. The old macfs.StandardGetFile and friends are deprecated. + + - Most of the standard library now uses pathnames or FSRefs in preference + of FSSpecs, and use the underlying Carbon.File and Carbon.Folder modules + in stead of macfs. macfs will probably be deprecated in the future. - Type Carbon.File.FSCatalogInfo and supporting methods have been implemented. From jackjansen@users.sourceforge.net Thu Feb 6 23:12:27 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 06 Feb 2003 15:12:27 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac Audio_mac.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv28870 Modified Files: Audio_mac.py Log Message: Got rid of macfs and FSSpecs. Index: Audio_mac.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/Audio_mac.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Audio_mac.py 30 Dec 2002 22:04:20 -0000 1.1 --- Audio_mac.py 6 Feb 2003 23:12:23 -0000 1.2 *************** *** 101,108 **** def test(): import aifc ! import macfs ! fss, ok = macfs.PromptGetFile("Select an AIFF soundfile", "AIFF") ! if not ok: return ! fn = fss.as_pathname() af = aifc.open(fn, 'r') print af.getparams() --- 101,107 ---- def test(): import aifc ! import EasyDialogs ! fn = EasyDialogs.AskFileForOpen(message="Select an AIFF soundfile", typeList=("AIFF",)) ! if not fn: return af = aifc.open(fn, 'r') print af.getparams() From jackjansen@users.sourceforge.net Thu Feb 6 23:13:13 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 06 Feb 2003 15:13:13 -0800 Subject: [Python-checkins] python/dist/src/Mac/scripts fixfiletypes.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv29244 Modified Files: fixfiletypes.py Log Message: Got rid of macfs. Index: fixfiletypes.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/fixfiletypes.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** fixfiletypes.py 26 Jan 2003 21:40:00 -0000 1.7 --- fixfiletypes.py 6 Feb 2003 23:13:11 -0000 1.8 *************** *** 9,16 **** # import os - import macfs import EasyDialogs import sys import macostools list = [ --- 9,16 ---- # import os import EasyDialogs import sys import macostools + import MacOS list = [ *************** *** 31,39 **** for ext, cr, tp in list: if name[-len(ext):] == ext: ! fs = macfs.FSSpec(name) ! curcrtp = fs.GetCreatorType() if curcrtp <> (cr, tp): if change: ! fs.SetCreatorType(cr, tp) macostools.touched(fs) print 'Fixed ', name --- 31,38 ---- for ext, cr, tp in list: if name[-len(ext):] == ext: ! curcrtp = MacOS.GetCreatorAndType(name) if curcrtp <> (cr, tp): if change: ! MacOS.SetCreatorAndType(name, cr, tp) macostools.touched(fs) print 'Fixed ', name *************** *** 53,57 **** if __name__ == '__main__': ! run(1) --- 52,56 ---- if __name__ == '__main__': ! run(0) From nnorwitz@users.sourceforge.net Thu Feb 6 21:17:21 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Thu, 06 Feb 2003 13:17:21 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libfilecmp.tex,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv30719/Doc/lib Modified Files: libfilecmp.tex Log Message: Update doc to reflect code changes for obsoleting use_statcache parameter Index: libfilecmp.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfilecmp.tex,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** libfilecmp.tex 5 Apr 2002 02:21:09 -0000 1.7 --- libfilecmp.tex 6 Feb 2003 21:17:17 -0000 1.8 *************** *** 17,30 **** Unless \var{shallow} is given and is false, files with identical ! \function{os.stat()} signatures are taken to be equal. If ! \var{use_statcache} is given and is true, ! \function{statcache.stat()} will be called rather then ! \function{os.stat()}; the default is to use \function{os.stat()}. Files that were compared using this function will not be compared again ! unless their \function{os.stat()} signature changes. Note that using ! \var{use_statcache} true will cause the cache invalidation mechanism to ! fail --- the stale stat value will be used from \refmodule{statcache}'s ! cache. Note that no external programs are called from this function, giving it --- 17,25 ---- Unless \var{shallow} is given and is false, files with identical ! \function{os.stat()} signatures are taken to be equal. ! \versionchanged[\var{use_statcache} is obsolete and ignored.]{2.3} Files that were compared using this function will not be compared again ! unless their \function{os.stat()} signature changes. Note that no external programs are called from this function, giving it From andrewmcnamara@users.sourceforge.net Fri Feb 7 01:27:23 2003 From: andrewmcnamara@users.sourceforge.net (andrewmcnamara@users.sourceforge.net) Date: Thu, 06 Feb 2003 17:27:23 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.16,1.17 csv.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv6805 Modified Files: _csv.c csv.py Log Message: Extensive re-write of C extension module - most of the code that was in csv.py has moved into the extension module. 16 tests now fail due to changed API and will need work. Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** _csv.c 5 Feb 2003 10:30:06 -0000 1.16 --- _csv.c 7 Feb 2003 01:27:21 -0000 1.17 *************** *** 1,15 **** /* TODO: - + Add reader() and writer() functions which return CSV - reader/writer objects which implement the PEP interface: - - csvreader = csv.reader(file("blah.csv", "rb"), kwargs) - for row in csvreader: - process(row) - - csvwriter = csv.writer(file("some.csv", "wb"), kwargs) - for row in someiter: [...1621 lines suppressed...] if (v == NULL) return; ! res = PyModule_AddObject(module, style->name, v); if (res < 0) return; *************** *** 981,988 **** if (error_obj == NULL) return; ! ! PyDict_SetItemString(dict, "Error", error_obj); ! ! Py_XDECREF(rev); ! Py_XDECREF(error_obj); } --- 1201,1204 ---- if (error_obj == NULL) return; ! PyModule_AddObject(module, "Error", error_obj); } Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** csv.py 6 Feb 2003 04:49:29 -0000 1.23 --- csv.py 7 Feb 2003 01:27:21 -0000 1.24 *************** *** 1,5 **** ! import _csv ! from _csv import Error, __version__ ! from _csv import QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE __all__ = [ "QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", --- 1,5 ---- ! from _csv import Error, __version__, writer, reader, register_dialect, \ ! unregister_dialect, get_dialect, list_dialects, \ ! QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE __all__ = [ "QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", *************** *** 8,31 **** "unregister_dialect", "__version__" ] - _dialects = {} - - def register_dialect(name, dialect): - if not issubclass(dialect, Dialect): - raise TypeError, "dialect not a subclass of Dialect" - if dialect == Dialect: - raise ValueError, "Dialect is an abstract class" - d = dialect() - dialect._name = name - _dialects[name] = d - - def get_dialect(name): - return _dialects[name] - - def list_dialects(): - return _dialects.keys() - - def unregister_dialect(name): - del _dialects[name] - class Dialect: _name = "" --- 8,11 ---- *************** *** 75,156 **** delimiter = '\t' register_dialect("excel-tab", excel_tab) - - class _OCcsv: - def __init__(self, dialect, **options): - if isinstance(dialect, Dialect): - dialect_obj = dialect - else: - try: - dialect_obj = _dialects[dialect] - except KeyError: - raise Error('Unknown dialect') - parser_options = {} - for attr in dir(dialect_obj): - if attr.startswith('_'): - continue - parser_options[attr] = getattr(dialect_obj, attr) - parser_options.update(options) - self.parser = _csv.parser(**parser_options) - - class reader(_OCcsv): - def __init__(self, iterobj, dialect = 'excel', - fieldnames=None, restfield=None, - **options): - self.iterobj = iter(iterobj) - self.fieldnames = fieldnames - self.restfield = restfield - _OCcsv.__init__(self, dialect, **options) - - def __iter__(self): - return self - - def next(self): - while 1: - fields = self.parser.parse(self.iterobj.next()) - if fields: - if self.fieldnames is not None: - lf = len(self.fieldnames) - result = dict(zip(self.fieldnames, fields)) - if (lf < len(fields) and - self.restfield is not None): - result[self.restfield] = fields[lf:] - return result - return fields - - class writer(_OCcsv): - def __init__(self, fileobj, dialect='excel', fieldnames=None, **options): - self.fileobj = fileobj - self.fieldnames = fieldnames - _OCcsv.__init__(self, dialect, **options) - - def writerow(self, fields): - # if fields is a dict, we need a valid fieldnames list - # if self.fieldnames is None we'll get a TypeError in the for stmt - # if fields is not a dict we'll get an AttributeError on .get() - try: - flist = [] - for k in self.fieldnames: - flist.append(fields.get(k, "")) - fields = flist - except (TypeError, AttributeError): - pass - self.fileobj.write(self.parser.join(fields)) - - def writerows(self, lines): - for fields in lines: - self.writerow(fields) - - # An alternate way of populating the dialects dictionary... - #def _init_dialects(): - # global _dialects - # mod = sys.modules[__name__] - # for name in dir(mod): - # attr = getattr(mod, name) - # try: - # if issubclass(attr, Dialect) and attr is not Dialect: - # dialect = attr() - # _dialects[dialect.name] = dialect - # except TypeError: - # pass - # - #_init_dialects() --- 55,56 ---- From tim_one@users.sourceforge.net Fri Feb 7 01:53:50 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 06 Feb 2003 17:53:50 -0800 Subject: [Python-checkins] python/dist/src/Lib pydoc.py,1.74,1.75 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv20760/Lib Modified Files: pydoc.py Log Message: SF bug 666444: 'help' makes linefeed only under Win32. Reverting one of those irritating "security fixes". fdopen() opens files in binary mode. That makes pydoc skip the \r\n on Windows that's need to make the output readable in the shell. Screw it. Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.74 retrieving revision 1.75 diff -C2 -d -r1.74 -r1.75 *** pydoc.py 28 Dec 2002 09:23:08 -0000 1.74 --- pydoc.py 7 Feb 2003 01:53:46 -0000 1.75 *************** *** 1230,1235 **** """Page through text by invoking a program on a temporary file.""" import tempfile ! (fd, filename) = tempfile.mkstemp() ! file = os.fdopen(fd, 'w') file.write(text) file.close() --- 1230,1235 ---- """Page through text by invoking a program on a temporary file.""" import tempfile ! filename = tempfile.mktemp() ! file = open(filename, 'w') file.write(text) file.close() From fdrake@users.sourceforge.net Fri Feb 7 02:15:58 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Thu, 06 Feb 2003 18:15:58 -0800 Subject: [Python-checkins] python/dist/src/Modules/expat expat.h,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Modules/expat In directory sc8-pr-cvs1:/tmp/cvs-serv2387 Modified Files: expat.h Log Message: Integrate the patch from expat.h 1.51; needed for some C compilers. Closes SF bug #680797. Index: expat.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/expat/expat.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** expat.h 25 Jan 2003 22:41:29 -0000 1.4 --- expat.h 7 Feb 2003 02:15:56 -0000 1.5 *************** *** 58,61 **** --- 58,81 ---- #define XML_FALSE ((XML_Bool) 0) + /* The XML_Status enum gives the possible return values for several + API functions. The preprocessor #defines are included so this + stanza can be added to code that still needs to support older + versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been + dropped. + */ + enum XML_Status { + XML_STATUS_ERROR = 0, + #define XML_STATUS_ERROR XML_STATUS_ERROR + XML_STATUS_OK = 1 + #define XML_STATUS_OK XML_STATUS_OK + }; + enum XML_Error { XML_ERROR_NONE, *************** *** 718,743 **** may be zero for this call (or any other). ! The XML_Status enum gives the possible return values for the ! XML_Parse and XML_ParseBuffer functions. Though the return values ! for these functions has always been described as a Boolean value, ! the implementation, at least for the 1.95.x series, has always ! returned exactly one of these values. The preprocessor #defines ! are included so this stanza can be added to code that still needs ! to support older versions of Expat 1.95.x: ! ! #ifndef XML_STATUS_OK ! #define XML_STATUS_OK 1 ! #define XML_STATUS_ERROR 0 ! #endif ! ! Otherwise, the #define hackery is quite ugly and would have been dropped. */ - enum XML_Status { - XML_STATUS_ERROR = 0, - #define XML_STATUS_ERROR XML_STATUS_ERROR - XML_STATUS_OK = 1 - #define XML_STATUS_OK XML_STATUS_OK - }; - XMLPARSEAPI(enum XML_Status) XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); --- 738,746 ---- may be zero for this call (or any other). ! Though the return values for these functions has always been ! described as a Boolean value, the implementation, at least for the ! 1.95.x series, has always returned exactly one of the XML_Status ! values. */ XMLPARSEAPI(enum XML_Status) XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); From nnorwitz@users.sourceforge.net Fri Feb 7 02:27:40 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Thu, 06 Feb 2003 18:27:40 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libos.tex,1.110,1.111 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv8140/lib Modified Files: libos.tex Log Message: Fix SF bug #675259, os.environ leaks under FreeBSD and Mac OS X Even with the extra work to cleanup the env, *BSD still leaks. Add a note. Will backport. Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.110 retrieving revision 1.111 diff -C2 -d -r1.110 -r1.111 *** libos.tex 3 Feb 2003 15:36:26 -0000 1.110 --- libos.tex 7 Feb 2003 02:27:36 -0000 1.111 *************** *** 94,98 **** mapping may be used to modify the environment as well as query the environment. \function{putenv()} will be called automatically when ! the mapping is modified. If \function{putenv()} is not provided, this mapping may be passed to --- 94,100 ---- mapping may be used to modify the environment as well as query the environment. \function{putenv()} will be called automatically when ! the mapping is modified. \note{On some platforms, including ! FreeBSD and Mac OS X, setting \code{environ} may cause memory leaks. ! Refer to the system documentation for putenv.} If \function{putenv()} is not provided, this mapping may be passed to *************** *** 193,196 **** --- 195,202 ---- \function{fork()} and \function{execv()}. Availability: most flavors of \UNIX, Windows. + + \note{On some platforms, including FreeBSD and Mac OS X, + setting \code{environ} may cause memory leaks. + Refer to the system documentation for putenv.} When \function{putenv()} is From nnorwitz@users.sourceforge.net Fri Feb 7 02:29:03 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Thu, 06 Feb 2003 18:29:03 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libos.tex,1.74.2.1.2.9,1.74.2.1.2.10 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv9178/Doc/lib Modified Files: Tag: release22-maint libos.tex Log Message: Fix SF bug #675259, os.environ leaks under FreeBSD and Mac OS X Even with the extra work to cleanup the env, *BSD still leaks. Add a note. Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.74.2.1.2.9 retrieving revision 1.74.2.1.2.10 diff -C2 -d -r1.74.2.1.2.9 -r1.74.2.1.2.10 *** libos.tex 6 Dec 2002 16:43:48 -0000 1.74.2.1.2.9 --- libos.tex 7 Feb 2003 02:29:01 -0000 1.74.2.1.2.10 *************** *** 94,98 **** mapping may be used to modify the environment as well as query the environment. \function{putenv()} will be called automatically when ! the mapping is modified. If \function{putenv()} is not provided, this mapping may be passed to --- 94,100 ---- mapping may be used to modify the environment as well as query the environment. \function{putenv()} will be called automatically when ! the mapping is modified. \note{On some platforms, including ! FreeBSD and Mac OS X, setting \code{environ} may cause memory leaks. ! Refer to the system documentation for putenv.} If \function{putenv()} is not provided, this mapping may be passed to *************** *** 182,185 **** --- 184,191 ---- \function{fork()} and \function{execv()}. Availability: most flavors of \UNIX, Windows. + + \note{On some platforms, including FreeBSD and Mac OS X, + setting \code{environ} may cause memory leaks. + Refer to the system documentation for putenv.} When \function{putenv()} is From andrewmcnamara@users.sourceforge.net Fri Feb 7 02:36:28 2003 From: andrewmcnamara@users.sourceforge.net (andrewmcnamara@users.sourceforge.net) Date: Thu, 06 Feb 2003 18:36:28 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.17,1.18 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv12758 Modified Files: _csv.c Log Message: Updated module docstring to match current API. Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** _csv.c 7 Feb 2003 01:27:21 -0000 1.17 --- _csv.c 7 Feb 2003 02:36:25 -0000 1.18 *************** *** 1111,1155 **** */ - static struct PyMethodDef csv_methods[] = { - { "reader", (PyCFunction)csv_reader, METH_VARARGS | METH_KEYWORDS}, - { "writer", (PyCFunction)csv_writer, METH_VARARGS | METH_KEYWORDS}, - { "list_dialects", (PyCFunction)csv_list_dialects, METH_VARARGS}, - { "register_dialect", (PyCFunction)csv_register_dialect, METH_VARARGS}, - { "unregister_dialect", (PyCFunction)csv_unregister_dialect, METH_VARARGS}, - { "get_dialect", (PyCFunction)csv_get_dialect, METH_VARARGS}, - { NULL, NULL } - }; - PyDoc_STRVAR(csv_module_doc, ! "This module provides class for performing CSV parsing and writing.\n" "\n" ! "The CSV parser object (returned by the parser() function) supports the\n" ! "following methods:\n" ! " clear()\n" ! " Discards all fields parsed so far. If autoclear is set to\n" ! " zero. You should call this after a parser exception.\n" "\n" - " parse(string) -> list of strings\n" - " Extracts fields from the (partial) CSV record in string.\n" - " Trailing end of line characters are ignored, so you do not\n" - " need to strip the string before passing it to the parser. If\n" - " you pass more than a single line of text, a _csv.Error\n" - " exception will be raised.\n" "\n" ! " join(sequence) -> string\n" ! " Construct a CSV record from a sequence of fields. Non-string\n" ! " elements will be converted to string.\n" "\n" ! "Typical usage:\n" "\n" ! " import _csv\n" ! " p = _csv.parser()\n" ! " fp = open('afile.csv', 'U')\n" ! " for line in fp:\n" ! " fields = p.parse(line)\n" ! " if not fields:\n" ! " # multi-line record\n" ! " continue\n" ! " # process the fields\n"); PyMODINIT_FUNC --- 1111,1229 ---- */ PyDoc_STRVAR(csv_module_doc, ! "CSV parsing and writing.\n" "\n" ! "This module provides classes that assist in the reading and writing\n" ! "of Comma Separated Value (CSV) files, and implements the interface\n" ! "described by PEP 305. Although many CSV files are simple to parse,\n" ! "the format is not formally defined by a stable specification and\n" ! "is subtle enough that parsing lines of a CSV file with something\n" ! "like line.split(\",\") is bound to fail. The module supports three\n" ! "basic APIs: reading, writing, and registration of dialects.\n" "\n" "\n" ! "READING:\n" "\n" ! "The reader interface is provided by a factory function \"reader\":\n" "\n" ! " csv_reader = reader(iterable [, dialect='excel']\n" ! " [optional keyword args])\n" ! " for row in csv_reader:\n" ! " process(row)\n" ! "\n" ! "The \"iterable\" argument can be any object that returns a line\n" ! "of input for each iteration, such as a file object or a list. The\n" ! "optional \"dialect\" parameter is discussed below. The function\n" ! "also accepts optional keyword arguments which override settings\n" ! "provided by the dialect.\n" ! "\n" ! "The returned object is an iterator. Each iteration returns a row\n" ! "of the CSV file (which can span multiple input lines):\n" ! "\n" ! "\n" ! "WRITING:\n" ! "\n" ! "The writer interface is provided by a factory function \"writer\":\n" ! "\n" ! " csv_writer = csv.writer(fileobj [, dialect='excel']\n" ! " [optional keyword args])\n" ! " for row in csv_writer:\n" ! " csv_writer.writerow(row)\n" ! "\n" ! " [or]\n" ! "\n" ! " csv_writer = csv.writer(fileobj [, dialect='excel']\n" ! " [optional keyword args])\n" ! " csv_writer.writerows(rows)\n" ! "\n" ! "The \"fileobj\" argument can be any object that supports the file API.\n" ! "\n" ! "\n" ! "DIALECT REGISTRATION:\n" ! "\n" ! "Readers and writers support a dialect argument, which is a convient\n" ! "handle on a group of settings. When the dialect argument is a string,\n" ! "it identifies one of the dialects registered with the module. If it\n" ! "is a class or instance, the attributes of the argument are used as the\n" ! "settings for the reader or writer:\n" ! "\n" ! " class excel:\n" ! " delimiter = ','\n" ! " quotechar = '\"'\n" ! " escapechar = None\n" ! " doublequote = True\n" ! " skipinitialspace = False\n" ! " lineterminator = '\r\n'\n" ! " quoting = QUOTE_MINIMAL\n" ! "\n" ! "The dialect registry is supported by four functions:\n" ! "\n" ! " list_dialects()\n" ! " register_dialect(name, dialect)\n" ! " unregister_dialect(name)\n" ! " get_dialect(name)\n" ! "\n" ! "SETTINGS:\n" ! "\n" ! " * quotechar - specifies a one-character string to use as the \n" ! " quoting character. It defaults to '\"'.\n" ! " * delimiter - specifies a one-character string to use as the \n" ! " field separator. It defaults to ','.\n" ! " * escapechar - specifies a one-character string used to escape \n" ! " the delimiter when quoting is set to QUOTE_NONE.\n" ! " * skipinitialspace - specifies how to interpret whitespace which\n" ! " immediately follows a delimiter. It defaults to False, which\n" ! " means that whitespace immediately following a delimiter is part\n" ! " of the following field.\n" ! " * lineterminator - specifies the character sequence which should \n" ! " terminate rows.\n" ! " * quoting - controls when quotes should be generated by the writer.\n" ! " It can take on any of the following module constants:\n" ! "\n" ! " csv.QUOTE_MINIMAL means only when required, for example, when a\n" ! " field contains either the quotechar or the delimiter\n" ! " csv.QUOTE_ALL means that quotes are always placed around fields.\n" ! " csv.QUOTE_NONNUMERIC means that quotes are always placed around\n" ! " fields which contain characters other than [+-0-9.].\n" ! " csv.QUOTE_NONE means that quotes are never placed around fields.\n" ! " * doublequote - controls the handling of quotes inside fields. When\n" ! " True two consecutive quotes are interpreted as one during read,\n" ! " and when writing, each quote is written as two quotes\n"); ! ! static struct PyMethodDef csv_methods[] = { ! { "reader", (PyCFunction)csv_reader, ! METH_VARARGS | METH_KEYWORDS, csv_module_doc}, ! { "writer", (PyCFunction)csv_writer, ! METH_VARARGS | METH_KEYWORDS, csv_module_doc}, ! { "list_dialects", (PyCFunction)csv_list_dialects, ! METH_VARARGS, csv_module_doc}, ! { "register_dialect", (PyCFunction)csv_register_dialect, ! METH_VARARGS, csv_module_doc}, ! { "unregister_dialect", (PyCFunction)csv_unregister_dialect, ! METH_VARARGS, csv_module_doc}, ! { "get_dialect", (PyCFunction)csv_get_dialect, ! METH_VARARGS, csv_module_doc}, ! { NULL, NULL } ! }; PyMODINIT_FUNC From andrewmcnamara@users.sourceforge.net Fri Feb 7 04:46:27 2003 From: andrewmcnamara@users.sourceforge.net (andrewmcnamara@users.sourceforge.net) Date: Thu, 06 Feb 2003 20:46:27 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.18,1.19 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv14308 Modified Files: _csv.c Log Message: Commented out tests that were failing due to changed API, added tests for dialect registry, fixed bugs in dialect registry... 8-) Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** _csv.c 7 Feb 2003 02:36:25 -0000 1.18 --- _csv.c 7 Feb 2003 04:46:25 -0000 1.19 *************** *** 317,326 **** } static int ! parse_dialect_args(PyObject * self, PyObject * dia_inst, PyObject * kwargs) { PyObject * name_obj, * value_obj; ! Py_XINCREF(dia_inst); if (kwargs != NULL) { PyObject * key = PyString_FromString("dialect"); --- 317,339 ---- } + static PyObject * + get_dialect_from_registry(PyObject * name_obj) + { + PyObject *dialect_obj; + + dialect_obj = PyDict_GetItem(dialects, name_obj); + if (dialect_obj == NULL) + return PyErr_Format(error_obj, "unknown dialect '%s'", + PyString_AsString(name_obj)); + Py_INCREF(dialect_obj); + return dialect_obj; + } + static int ! parse_dialect_args(PyObject * self, PyObject * dialect, PyObject * kwargs) { PyObject * name_obj, * value_obj; ! Py_XINCREF(dialect); if (kwargs != NULL) { PyObject * key = PyString_FromString("dialect"); *************** *** 330,368 **** if (d) { Py_INCREF(d); ! Py_XDECREF(dia_inst); PyDict_DelItem(kwargs, key); ! dia_inst = d; } Py_DECREF(key); } ! if (dia_inst != NULL) { int i; PyObject * dir_list; /* If dialect is a string, look it up in our registry */ ! if (PyString_Check(dia_inst) || PyUnicode_Check(dia_inst)) { PyObject * new_dia; ! new_dia = PyDict_GetItem(dialects, dia_inst); ! Py_DECREF(dia_inst); if (new_dia == NULL) return 0; ! Py_INCREF(new_dia); ! dia_inst = new_dia; } /* A class rather than an instance? Instanciate */ ! if (PyObject_TypeCheck(dia_inst, &PyClass_Type)) { PyObject * new_dia; ! new_dia = PyObject_CallFunction(dia_inst, ""); ! Py_DECREF(dia_inst); if (new_dia == NULL) return 0; ! dia_inst = new_dia; } /* Make sure we finally have an instance */ ! if (!PyInstance_Check(dia_inst) || ! (dir_list = PyObject_Dir(dia_inst)) == NULL) { PyErr_SetString(PyExc_TypeError, "dialect must be an instance"); ! Py_DECREF(dia_inst); return 0; } --- 343,380 ---- if (d) { Py_INCREF(d); ! Py_XDECREF(dialect); PyDict_DelItem(kwargs, key); ! dialect = d; } Py_DECREF(key); } ! if (dialect != NULL) { int i; PyObject * dir_list; /* If dialect is a string, look it up in our registry */ ! if (PyString_Check(dialect) || PyUnicode_Check(dialect)) { PyObject * new_dia; ! new_dia = get_dialect_from_registry(dialect); ! Py_DECREF(dialect); if (new_dia == NULL) return 0; ! dialect = new_dia; } /* A class rather than an instance? Instanciate */ ! if (PyObject_TypeCheck(dialect, &PyClass_Type)) { PyObject * new_dia; ! new_dia = PyObject_CallFunction(dialect, ""); ! Py_DECREF(dialect); if (new_dia == NULL) return 0; ! dialect = new_dia; } /* Make sure we finally have an instance */ ! if (!PyInstance_Check(dialect) || ! (dir_list = PyObject_Dir(dialect)) == NULL) { PyErr_SetString(PyExc_TypeError, "dialect must be an instance"); ! Py_DECREF(dialect); return 0; } *************** *** 372,376 **** if (PyString_AsString(name_obj)[0] == '_') continue; ! value_obj = PyObject_GetAttr(dia_inst, name_obj); if (value_obj) { if (PyObject_SetAttr(self, name_obj, --- 384,388 ---- if (PyString_AsString(name_obj)[0] == '_') continue; ! value_obj = PyObject_GetAttr(dialect, name_obj); if (value_obj) { if (PyObject_SetAttr(self, name_obj, *************** *** 383,387 **** } Py_DECREF(dir_list); ! Py_DECREF(dia_inst); } if (kwargs != NULL) { --- 395,399 ---- } Py_DECREF(dir_list); ! Py_DECREF(dialect); } if (kwargs != NULL) { *************** *** 1090,1094 **** return NULL; if (PyDict_DelItem(dialects, name_obj) < 0) ! return NULL; Py_INCREF(Py_None); return Py_None; --- 1102,1107 ---- return NULL; if (PyDict_DelItem(dialects, name_obj) < 0) ! return PyErr_Format(error_obj, "unknown dialect '%s'", ! PyString_AsString(name_obj)); Py_INCREF(Py_None); return Py_None; *************** *** 1098,1108 **** csv_get_dialect(PyObject *module, PyObject *args) { ! PyObject *name_obj, *dialect_obj; if (!PyArg_ParseTuple(args, "O!", &PyBaseString_Type, &name_obj)) return NULL; ! dialect_obj = PyDict_GetItem(dialects, name_obj); ! Py_XINCREF(dialect_obj); ! return dialect_obj; } --- 1111,1119 ---- csv_get_dialect(PyObject *module, PyObject *args) { ! PyObject *name_obj; if (!PyArg_ParseTuple(args, "O!", &PyBaseString_Type, &name_obj)) return NULL; ! return get_dialect_from_registry(name_obj); } From andrewmcnamara@users.sourceforge.net Fri Feb 7 04:46:27 2003 From: andrewmcnamara@users.sourceforge.net (andrewmcnamara@users.sourceforge.net) Date: Thu, 06 Feb 2003 20:46:27 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv14308/test Modified Files: test_csv.py Log Message: Commented out tests that were failing due to changed API, added tests for dialect registry, fixed bugs in dialect registry... 8-) Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** test_csv.py 6 Feb 2003 04:51:47 -0000 1.20 --- test_csv.py 7 Feb 2003 04:46:25 -0000 1.21 *************** *** 8,12 **** import _csv ! class Test_Csv(unittest.TestCase): """ Test the underlying C csv parser in ways that are not appropriate --- 8,13 ---- import _csv ! # Disabled pending update to new API ! class xTest_Csv(unittest.TestCase): """ Test the underlying C csv parser in ways that are not appropriate *************** *** 241,245 **** self.readerAssertEqual('"abc\\,def"\r\n', [['abc,def']]) ! class TestDictFields(unittest.TestCase): def test_write_simple_dict(self): fileobj = StringIO() --- 242,247 ---- self.readerAssertEqual('"abc\\,def"\r\n', [['abc,def']]) ! # Disabled, pending support in csv.utils module ! class xTestDictFields(unittest.TestCase): def test_write_simple_dict(self): fileobj = StringIO() *************** *** 310,336 **** self.assertEqual(fileobj.getvalue(), expected) ! class TestDialects(unittest.TestCase): ! def test_register(self): ! class myexceltsv(csv.excel): ! delimiter = "\t" ! csv.register_dialect("myexceltsv", myexceltsv) ! self.assertEqual(isinstance(csv.get_dialect("myexceltsv"), ! myexceltsv), 1==1) ! csv.unregister_dialect("myexceltsv") ! ! def test_get(self): ! self.assertEqual(isinstance(csv.get_dialect("excel"), ! csv.excel), 1==1) ! ! def test_list(self): ! for dname in csv.list_dialects(): ! d = csv.get_dialect(dname) ! self.assertEqual(d._name, dname) ! def test_bad_register(self): ! class myexceltsv: delimiter = "\t" ! self.assertRaises(TypeError, csv.register_dialect, ! "myexceltsv", myexceltsv) def test_incomplete_dialect(self): --- 312,343 ---- self.assertEqual(fileobj.getvalue(), expected) ! class TestDialectRegistry(unittest.TestCase): ! def test_registry_badargs(self): ! self.assertRaises(TypeError, csv.list_dialects, None) ! self.assertRaises(TypeError, csv.get_dialect, None) ! self.assertRaises(csv.Error, csv.get_dialect, "nonesuch") ! self.assertRaises(TypeError, csv.unregister_dialect, None) ! self.assertRaises(csv.Error, csv.unregister_dialect, "nonesuch") ! self.assertRaises(TypeError, csv.register_dialect, None) ! self.assertRaises(TypeError, csv.register_dialect, "nonesuch", None) ! class bogus: ! def __init__(self): ! raise KeyError ! self.assertRaises(KeyError, csv.register_dialect, "nonesuch", bogus) ! def test_registry(self): ! class myexceltsv(csv.excel): delimiter = "\t" ! name = "myexceltsv" ! expected_dialects = csv.list_dialects() + [name] ! expected_dialects.sort() ! csv.register_dialect(name, myexceltsv) ! try: ! self.failUnless(isinstance(csv.get_dialect(name), myexceltsv)) ! got_dialects = csv.list_dialects() ! got_dialects.sort() ! self.assertEqual(expected_dialects, got_dialects) ! finally: ! csv.unregister_dialect(name) def test_incomplete_dialect(self): *************** *** 339,349 **** self.assertRaises(csv.Error, myexceltsv) ! def test_dialect_class(self): ! class myexceltsv(csv.excel): delimiter = "\t" ! fileobj = StringIO() ! writer = csv.writer(fileobj, dialect=myexceltsv()) ! writer.writerow([1,2,3]) ! self.assertEqual(fileobj.getvalue(), "1\t2\t3\r\n") --- 346,385 ---- self.assertRaises(csv.Error, myexceltsv) ! def test_dialect_apply(self): ! class testA(csv.excel): delimiter = "\t" ! class testB(csv.excel): ! delimiter = ":" ! class testC(csv.excel): ! delimiter = "|" ! ! csv.register_dialect('testC', testC) ! try: ! fileobj = StringIO() ! writer = csv.writer(fileobj) ! writer.writerow([1,2,3]) ! self.assertEqual(fileobj.getvalue(), "1,2,3\r\n") ! ! fileobj = StringIO() ! writer = csv.writer(fileobj, testA) ! writer.writerow([1,2,3]) ! self.assertEqual(fileobj.getvalue(), "1\t2\t3\r\n") ! ! fileobj = StringIO() ! writer = csv.writer(fileobj, dialect=testB()) ! writer.writerow([1,2,3]) ! self.assertEqual(fileobj.getvalue(), "1:2:3\r\n") ! ! fileobj = StringIO() ! writer = csv.writer(fileobj, dialect='testC') ! writer.writerow([1,2,3]) ! self.assertEqual(fileobj.getvalue(), "1|2|3\r\n") ! ! fileobj = StringIO() ! writer = csv.writer(fileobj, dialect=testA, delimiter=';') ! writer.writerow([1,2,3]) ! self.assertEqual(fileobj.getvalue(), "1;2;3\r\n") ! finally: ! csv.unregister_dialect('testC') From rhettinger@users.sourceforge.net Fri Feb 7 05:33:00 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 06 Feb 2003 21:33:00 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_itertools.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv2842/Lib/test Modified Files: test_itertools.py Log Message: SF bug #681003: itertools issues * Fixed typo in exception message for times() * Filled in missing times_traverse() * Document reasons that imap() did not adopt a None fill-in feature * Document that count(sys.maxint) will wrap-around on overflow * Add overflow test to islice() * Check that starmap()'s argument returns a tuple * Verify that imap()'s tuple re-use is safe * Make a similar tuple re-use (with safety check) for izip() Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_itertools.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_itertools.py 1 Feb 2003 02:33:45 -0000 1.2 --- test_itertools.py 7 Feb 2003 05:32:58 -0000 1.3 *************** *** 2,5 **** --- 2,6 ---- from test import test_support from itertools import * + import sys class TestBasicOps(unittest.TestCase): *************** *** 48,51 **** --- 49,53 ---- self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))), [0**1, 1**2, 2**3]) + self.assertRaises(TypeError, list, starmap(operator.pow, [[4,5]])) def test_islice(self): *************** *** 72,75 **** --- 74,78 ---- self.assertRaises(ValueError, islice, xrange(10), 1, 10, -1) self.assertRaises(ValueError, islice, xrange(10), 1, 10, 0) + self.assertEqual(len(list(islice(count(), 1, 10, sys.maxint))), 1) def test_takewhile(self): From rhettinger@users.sourceforge.net Fri Feb 7 05:32:59 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 06 Feb 2003 21:32:59 -0800 Subject: [Python-checkins] python/dist/src/Modules itertoolsmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv2842/Modules Modified Files: itertoolsmodule.c Log Message: SF bug #681003: itertools issues * Fixed typo in exception message for times() * Filled in missing times_traverse() * Document reasons that imap() did not adopt a None fill-in feature * Document that count(sys.maxint) will wrap-around on overflow * Add overflow test to islice() * Check that starmap()'s argument returns a tuple * Verify that imap()'s tuple re-use is safe * Make a similar tuple re-use (with safety check) for izip() Index: itertoolsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/itertoolsmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** itertoolsmodule.c 1 Feb 2003 00:10:10 -0000 1.1 --- itertoolsmodule.c 7 Feb 2003 05:32:57 -0000 1.2 *************** *** 404,407 **** --- 404,408 ---- { PyObject *item; + long oldnext; while (lz->cnt < lz->next) { *************** *** 418,422 **** --- 419,426 ---- return NULL; lz->cnt++; + oldnext = lz->next; lz->next += lz->step; + if (lz->next < oldnext) /* Check for overflow */ + lz->next = lz->stop; return item; } *************** *** 559,562 **** --- 563,572 ---- if (args == NULL) return NULL; + if (!PyTuple_CheckExact(args)) { + Py_DECREF(args); + PyErr_SetString(PyExc_TypeError, + "iterator must return a tuple"); + return NULL; + } result = PyObject_Call(lz->func, args, NULL); Py_DECREF(args); *************** *** 720,723 **** --- 730,758 ---- } + /* + imap() is an iterator version of __builtins__.map() except that it does + not have the None fill-in feature. That was intentionally left out for + the following reasons: + + 1) Itertools are designed to be easily combined and chained together. + Having all tools stop with the shortest input is a unifying principle + that makes it easier to combine finite iterators (supplying data) with + infinite iterators like count() and repeat() (for supplying sequential + or constant arguments to a function). + + 2) In typical use cases for combining itertools, having one finite data + supplier run out before another is likely to be an error condition which + should not pass silently by automatically supplying None. + + 3) The use cases for automatic None fill-in are rare -- not many functions + do something useful when a parameter suddenly switches type and becomes + None. + + 4) If a need does arise, it can be met by __builtins__.map() or by + writing a generator. + + 5) Similar toolsets in Haskell and SML do not have automatic None fill-in. + */ + static PyObject * imap_next(imapobject *lz) *************** *** 743,746 **** --- 778,786 ---- return argtuple; } else { + if (argtuple->ob_refcnt > 1) { + argtuple = PyTuple_New(numargs); + if (argtuple == NULL) + return NULL; + } for (i=0 ; iiters, i)); *************** *** 838,842 **** if (cnt < 0) { PyErr_SetString(PyExc_ValueError, ! "count for imap() cannot be negative."); return NULL; } --- 878,882 ---- if (cnt < 0) { PyErr_SetString(PyExc_ValueError, ! "count for times() cannot be negative."); return NULL; } *************** *** 861,864 **** --- 901,912 ---- } + static int + times_traverse(timesobject *lz, visitproc visit, void *arg) + { + if (lz->obj) + return visit(lz->obj, arg); + return 0; + } + static PyObject * times_next(timesobject *lz) *************** *** 912,916 **** Py_TPFLAGS_BASETYPE, /* tp_flags */ times_doc, /* tp_doc */ ! 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ --- 960,964 ---- Py_TPFLAGS_BASETYPE, /* tp_flags */ times_doc, /* tp_doc */ ! (traverseproc)times_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ *************** *** 1192,1195 **** --- 1240,1244 ---- long tuplesize; PyObject *ittuple; /* tuple of iterators */ + PyObject *result; } izipobject; *************** *** 1202,1205 **** --- 1251,1255 ---- int i; PyObject *ittuple; /* tuple of iterators */ + PyObject *result; int tuplesize = PySequence_Length(args); *************** *** 1231,1242 **** --- 1281,1305 ---- } + /* create a result holder */ + result = PyTuple_New(tuplesize); + if (result == NULL) { + Py_DECREF(ittuple); + return NULL; + } + for (i=0 ; i < tuplesize ; i++) { + Py_INCREF(Py_None); + PyTuple_SET_ITEM(result, i, Py_None); + } + /* create izipobject structure */ lz = (izipobject *)type->tp_alloc(type, 0); if (lz == NULL) { Py_DECREF(ittuple); + Py_DECREF(result); return NULL; } lz->ittuple = ittuple; lz->tuplesize = tuplesize; + lz->result = result; return (PyObject *)lz; *************** *** 1248,1251 **** --- 1311,1315 ---- PyObject_GC_UnTrack(lz); Py_XDECREF(lz->ittuple); + Py_XDECREF(lz->result); lz->ob_type->tp_free(lz); } *************** *** 1264,1274 **** int i; long tuplesize = lz->tuplesize; ! PyObject *result; PyObject *it; PyObject *item; ! result = PyTuple_New(tuplesize); ! if (result == NULL) ! return NULL; for (i=0 ; i < tuplesize ; i++) { --- 1328,1352 ---- int i; long tuplesize = lz->tuplesize; ! PyObject *result = lz->result; PyObject *it; PyObject *item; ! assert(result->ob_refcnt >= 1); ! if (result->ob_refcnt == 1) { ! for (i=0 ; i < tuplesize ; i++) { ! Py_DECREF(PyTuple_GET_ITEM(result, i)); ! PyTuple_SET_ITEM(result, i, NULL); ! } ! Py_INCREF(result); ! } else { ! Py_DECREF(result); ! result = PyTuple_New(tuplesize); ! if (result == NULL) ! return NULL; ! Py_INCREF(result); ! lz->result = result; ! } ! assert(lz->result == result); ! assert(result->ob_refcnt == 2); for (i=0 ; i < tuplesize ; i++) { From rhettinger@users.sourceforge.net Fri Feb 7 05:33:00 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 06 Feb 2003 21:33:00 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libitertools.tex,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv2842/Doc/lib Modified Files: libitertools.tex Log Message: SF bug #681003: itertools issues * Fixed typo in exception message for times() * Filled in missing times_traverse() * Document reasons that imap() did not adopt a None fill-in feature * Document that count(sys.maxint) will wrap-around on overflow * Add overflow test to islice() * Check that starmap()'s argument returns a tuple * Verify that imap()'s tuple re-use is safe * Make a similar tuple re-use (with safety check) for izip() Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libitertools.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** libitertools.tex 1 Feb 2003 00:10:09 -0000 1.1 --- libitertools.tex 7 Feb 2003 05:32:57 -0000 1.2 *************** *** 83,86 **** --- 83,90 ---- cnt += 1 \end{verbatim} + + Note, \function{count()} does not check for overflow and will return + negative numbers after exceeding \code{sys.maxint}. This behavior + may change in the future. \end{funcdesc} From andrewmcnamara@users.sourceforge.net Fri Feb 7 06:33:02 2003 From: andrewmcnamara@users.sourceforge.net (andrewmcnamara@users.sourceforge.net) Date: Thu, 06 Feb 2003 22:33:02 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.19,1.20 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv7551 Modified Files: _csv.c Log Message: Improved the way we call self->writeline in writerow, fixed bug handling errors raised by PyIter_Next in writerows. Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** _csv.c 7 Feb 2003 04:46:25 -0000 1.19 --- _csv.c 7 Feb 2003 06:33:00 -0000 1.20 *************** *** 849,853 **** { int len, i; - PyObject *arglist, *result; if (!PySequence_Check(seq)) --- 849,852 ---- *************** *** 899,908 **** return 0; ! arglist = Py_BuildValue("(s#)", self->rec, self->rec_len); ! if (!arglist) ! return NULL; ! result = PyEval_CallObject(self->writeline, arglist); ! Py_DECREF(arglist); ! return result; } --- 898,903 ---- return 0; ! return PyEval_CallFunction(self->writeline, ! "(s#)", self->rec, self->rec_len); } *************** *** 929,932 **** --- 924,929 ---- } Py_DECREF(row_iter); + if (PyErr_Occurred()) + return NULL; Py_INCREF(Py_None); return Py_None; From andrewmcnamara@users.sourceforge.net Fri Feb 7 06:34:25 2003 From: andrewmcnamara@users.sourceforge.net (andrewmcnamara@users.sourceforge.net) Date: Thu, 06 Feb 2003 22:34:25 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv8246/test Modified Files: test_csv.py Log Message: Reinstated most of the tests broken by API changes, added many tests - have about 92% coverage now. Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** test_csv.py 7 Feb 2003 04:46:25 -0000 1.21 --- test_csv.py 7 Feb 2003 06:34:23 -0000 1.22 *************** *** 6,113 **** from StringIO import StringIO import csv - import _csv ! # Disabled pending update to new API ! class xTest_Csv(unittest.TestCase): """ Test the underlying C csv parser in ways that are not appropriate ! from the high level interface. """ ! def test_init(self): ! "test that the module returns a parser" ! parser = _csv.parser() ! self.failUnless(hasattr(parser, 'parse')) ! def test_parameter_validation(self): ! self.assertRaises(TypeError, _csv.parser, FlibbleWort = 0) ! self.assertRaises(ValueError, _csv.parser, quoting = -1) ! self.assertRaises(ValueError, _csv.parser, quoting = csv.QUOTE_NONE + 1) ! self.assertRaises(TypeError, _csv.parser, delimiter = None) ! self.assertRaises(TypeError, _csv.parser, skipinitialspace = None) ! def test_parameter(self): ! parser = _csv.parser(delimiter = "\t") ! self.assertEqual(parser.delimiter, "\t") ! parser = _csv.parser(quotechar = "'") ! self.assertEqual(parser.quotechar, "'") ! def test_attr_validation(self): ! parser = _csv.parser() ! self.assertRaises(AttributeError, delattr, parser, 'quoting') ! self.assertRaises(TypeError, setattr, parser, 'quoting', -1) ! self.assertRaises(TypeError, setattr, parser, 'quoting', ! csv.QUOTE_NONE + 1) ! self.assertRaises(TypeError, setattr, parser, 'quotechar', 0) ! self.assertRaises(TypeError, setattr, parser, 'escapechar', 0) ! self.assertRaises(TypeError, setattr, parser, 'lineterminator', None) ! def test_setattr(self): ! parser = _csv.parser() ! parser.delimiter = "\t" ! self.assertEqual(parser.delimiter, "\t") ! parser = _csv.parser() ! parser.quotechar = "'" ! self.assertEqual(parser.quotechar, "'") ! def test_join_bigfield(self): # This exercises the buffer realloc functionality - parser = _csv.parser() bigstring = 'X' * 50000 ! result = parser.join([bigstring,bigstring]) ! self.assertEqual(result, '%s,%s%s' % \ ! (bigstring, bigstring, parser.lineterminator)) ! def test_join_quoting(self): ! parser = _csv.parser() ! self.assertEqual(parser.join(['a','1','p,q']), 'a,1,"p,q"\r\n') ! parser = _csv.parser(quoting = csv.QUOTE_NONE) ! self.assertRaises(_csv.Error, parser.join, ['a','1','p,q']) ! parser = _csv.parser(quoting = csv.QUOTE_MINIMAL) ! self.assertEqual(parser.join(['a','1','p,q']), 'a,1,"p,q"\r\n') ! parser = _csv.parser(quoting = csv.QUOTE_NONNUMERIC) ! self.assertEqual(parser.join(['a','1','p,q']), '"a",1,"p,q"\r\n') ! parser = _csv.parser(quoting = csv.QUOTE_ALL) ! self.assertEqual(parser.join(['a','1','p,q']), '"a","1","p,q"\r\n') ! def test_join_escape(self): ! parser = _csv.parser(escapechar='\\') ! self.assertEqual(parser.join(['a','1','p,q']), 'a,1,"p,q"\r\n') ! parser.doublequote = 0 ! self.assertEqual(parser.join(['a','1','p,"q"']), 'a,1,"p,\\"q"\r\n') ! parser.quoting = csv.QUOTE_NONE ! self.assertEqual(parser.join(['a','1','p,q']), 'a,1,p\\,q\r\n') ! def test_parse(self): ! parser = _csv.parser() ! self.assertRaises(TypeError, parser.parse, None) ! self.assertEqual(parser.parse(''), []) ! def test_parse_eol(self): ! parser = _csv.parser() ! self.assertEqual(parser.parse('a,b'), ['a','b']) ! self.assertEqual(parser.parse('a,b\n'), ['a','b']) ! self.assertEqual(parser.parse('a,b\r\n'), ['a','b']) ! self.assertEqual(parser.parse('a,b\r'), ['a','b']) ! self.assertRaises(csv.Error, parser.parse, 'a,b\rc,d') ! self.assertRaises(csv.Error, parser.parse, 'a,b\nc,d') ! self.assertRaises(csv.Error, parser.parse, 'a,b\r\nc,d') ! def test_parse_escape(self): ! parser = _csv.parser(escapechar='\\') ! self.assertEqual(parser.parse('a,\\b,c'), ['a', '\\b', 'c']) ! self.assertEqual(parser.parse('a,b\\,c'), ['a', 'b,c']) ! self.assertEqual(parser.parse('a,"b\\,c"'), ['a', 'b,c']) ! self.assertEqual(parser.parse('a,"b,\\c"'), ['a', 'b,\\c']) ! self.assertEqual(parser.parse('a,"b,c\\""'), ['a', 'b,c"']) ! self.assertEqual(parser.parse('a,"b,c"\\'), ['a', 'b,c\\']) ! def test_parse_bigfield(self): # This exercises the buffer realloc functionality - parser = _csv.parser() bigstring = 'X' * 50000 ! bigline = '%s,%s%s' % (bigstring, bigstring, parser.lineterminator) ! self.assertEqual(parser.parse(bigline), [bigstring, bigstring]) class TestCsvBase(unittest.TestCase): --- 6,228 ---- from StringIO import StringIO import csv ! class Test_Csv(unittest.TestCase): """ Test the underlying C csv parser in ways that are not appropriate ! from the high level interface. Further tests of this nature are done ! in TestDialectRegistry. """ ! def test_reader_arg_valid(self): ! self.assertRaises(TypeError, csv.reader) ! self.assertRaises(TypeError, csv.reader, None) ! self.assertRaises(AttributeError, csv.reader, [], bad_attr = 0) ! self.assertRaises(csv.Error, csv.reader, [], 'foo') ! class BadClass: ! def __init__(self): ! raise IOError ! self.assertRaises(IOError, csv.reader, [], BadClass) ! self.assertRaises(TypeError, csv.reader, [], None) ! class BadDialect: ! bad_attr = 0 ! self.assertRaises(AttributeError, csv.reader, [], BadDialect) ! def test_writer_arg_valid(self): ! self.assertRaises(TypeError, csv.writer) ! self.assertRaises(TypeError, csv.writer, None) ! self.assertRaises(AttributeError, csv.writer, StringIO(), bad_attr = 0) ! def _test_attrs(self, obj): ! self.assertEqual(obj.delimiter, ',') ! obj.delimiter = '\t' ! self.assertEqual(obj.delimiter, '\t') ! self.assertRaises(AttributeError, delattr, obj, 'delimiter') ! self.assertRaises(TypeError, setattr, obj, 'lineterminator', None) ! obj.escapechar = None ! self.assertEqual(obj.escapechar, None) ! def test_reader_attrs(self): ! self._test_attrs(csv.reader([])) ! def test_writer_attrs(self): ! self._test_attrs(csv.writer(StringIO())) ! def _write_test(self, fields, expect, **kwargs): ! fileobj = StringIO() ! writer = csv.writer(fileobj, **kwargs) ! writer.writerow(fields) ! self.assertEqual(fileobj.getvalue(), expect + writer.lineterminator) ! def test_write_arg_valid(self): ! self.assertRaises(csv.Error, self._write_test, None, '') ! self._write_test((), '') ! self._write_test([None], '""') ! self.assertRaises(csv.Error, self._write_test, ! [None], None, quoting = csv.QUOTE_NONE) ! # Check that exceptions are passed up the chain ! class BadList: ! def __len__(self): ! return 10; ! def __getitem__(self, i): ! if i > 2: ! raise IOError ! self.assertRaises(IOError, self._write_test, BadList(), '') ! class BadItem: ! def __str__(self): ! raise IOError ! self.assertRaises(IOError, self._write_test, [BadItem()], '') ! def test_write_bigfield(self): # This exercises the buffer realloc functionality bigstring = 'X' * 50000 ! self._write_test([bigstring,bigstring], '%s,%s' % \ ! (bigstring, bigstring)) ! def test_write_quoting(self): ! self._write_test(['a','1','p,q'], 'a,1,"p,q"') ! self.assertRaises(csv.Error, ! self._write_test, ! ['a','1','p,q'], 'a,1,"p,q"', ! quoting = csv.QUOTE_NONE) ! self._write_test(['a','1','p,q'], 'a,1,"p,q"', ! quoting = csv.QUOTE_MINIMAL) ! self._write_test(['a','1','p,q'], '"a",1,"p,q"', ! quoting = csv.QUOTE_NONNUMERIC) ! self._write_test(['a','1','p,q'], '"a","1","p,q"', ! quoting = csv.QUOTE_ALL) ! def test_write_escape(self): ! self._write_test(['a','1','p,q'], 'a,1,"p,q"', ! escapechar='\\') ! # FAILED - needs to be fixed [am]: ! # self._write_test(['a','1','p,"q"'], 'a,1,"p,\\"q\\"', ! # escapechar='\\', doublequote = 0) ! self._write_test(['a','1','p,q'], 'a,1,p\\,q', ! escapechar='\\', quoting = csv.QUOTE_NONE) ! def test_writerows(self): ! class BrokenFile: ! def write(self, buf): ! raise IOError ! writer = csv.writer(BrokenFile()) ! self.assertRaises(IOError, writer.writerows, [['a']]) ! fileobj = StringIO() ! writer = csv.writer(fileobj) ! self.assertRaises(TypeError, writer.writerows, None) ! writer.writerows([['a','b'],['c','d']]) ! self.assertEqual(fileobj.getvalue(), "a,b\r\nc,d\r\n") ! def _read_test(self, input, expect, **kwargs): ! reader = csv.reader(input, **kwargs) ! result = list(reader) ! self.assertEqual(result, expect) ! def test_read_oddinputs(self): ! self._read_test([], []) ! self._read_test([''], [[]]) ! self.assertRaises(csv.Error, self._read_test, ! ['"ab"c'], None, strict = 1) ! self._read_test(['"ab"c'], [['abc']], doublequote = 0) ! def test_read_eol(self): ! self._read_test(['a,b'], [['a','b']]) ! self._read_test(['a,b\n'], [['a','b']]) ! self._read_test(['a,b\r\n'], [['a','b']]) ! self._read_test(['a,b\r'], [['a','b']]) ! self.assertRaises(csv.Error, self._read_test, ['a,b\rc,d'], []) ! self.assertRaises(csv.Error, self._read_test, ['a,b\nc,d'], []) ! self.assertRaises(csv.Error, self._read_test, ['a,b\r\nc,d'], []) ! ! def test_read_escape(self): ! self._read_test(['a,\\b,c'], [['a', '\\b', 'c']], escapechar='\\') ! self._read_test(['a,b\\,c'], [['a', 'b,c']], escapechar='\\') ! self._read_test(['a,"b\\,c"'], [['a', 'b,c']], escapechar='\\') ! self._read_test(['a,"b,\\c"'], [['a', 'b,\\c']], escapechar='\\') ! self._read_test(['a,"b,c\\""'], [['a', 'b,c"']], escapechar='\\') ! self._read_test(['a,"b,c"\\'], [['a', 'b,c\\']], escapechar='\\') ! ! def test_read_bigfield(self): # This exercises the buffer realloc functionality bigstring = 'X' * 50000 ! bigline = '%s,%s' % (bigstring, bigstring) ! self._read_test([bigline], [[bigstring, bigstring]]) ! ! class TestDialectRegistry(unittest.TestCase): ! def test_registry_badargs(self): ! self.assertRaises(TypeError, csv.list_dialects, None) ! self.assertRaises(TypeError, csv.get_dialect, None) ! self.assertRaises(csv.Error, csv.get_dialect, "nonesuch") ! self.assertRaises(TypeError, csv.unregister_dialect, None) ! self.assertRaises(csv.Error, csv.unregister_dialect, "nonesuch") ! self.assertRaises(TypeError, csv.register_dialect, None) ! self.assertRaises(TypeError, csv.register_dialect, "nonesuch", None) ! class bogus: ! def __init__(self): ! raise KeyError ! self.assertRaises(KeyError, csv.register_dialect, "nonesuch", bogus) ! ! def test_registry(self): ! class myexceltsv(csv.excel): ! delimiter = "\t" ! name = "myexceltsv" ! expected_dialects = csv.list_dialects() + [name] ! expected_dialects.sort() ! csv.register_dialect(name, myexceltsv) ! try: ! self.failUnless(isinstance(csv.get_dialect(name), myexceltsv)) ! got_dialects = csv.list_dialects() ! got_dialects.sort() ! self.assertEqual(expected_dialects, got_dialects) ! finally: ! csv.unregister_dialect(name) ! ! def test_incomplete_dialect(self): ! class myexceltsv(csv.Dialect): ! delimiter = "\t" ! self.assertRaises(csv.Error, myexceltsv) ! ! def test_dialect_apply(self): ! class testA(csv.excel): ! delimiter = "\t" ! class testB(csv.excel): ! delimiter = ":" ! class testC(csv.excel): ! delimiter = "|" ! ! csv.register_dialect('testC', testC) ! try: ! fileobj = StringIO() ! writer = csv.writer(fileobj) ! writer.writerow([1,2,3]) ! self.assertEqual(fileobj.getvalue(), "1,2,3\r\n") ! ! fileobj = StringIO() ! writer = csv.writer(fileobj, testA) ! writer.writerow([1,2,3]) ! self.assertEqual(fileobj.getvalue(), "1\t2\t3\r\n") ! ! fileobj = StringIO() ! writer = csv.writer(fileobj, dialect=testB()) ! writer.writerow([1,2,3]) ! self.assertEqual(fileobj.getvalue(), "1:2:3\r\n") ! ! fileobj = StringIO() ! writer = csv.writer(fileobj, dialect='testC') ! writer.writerow([1,2,3]) ! self.assertEqual(fileobj.getvalue(), "1|2|3\r\n") ! ! fileobj = StringIO() ! writer = csv.writer(fileobj, dialect=testA, delimiter=';') ! writer.writerow([1,2,3]) ! self.assertEqual(fileobj.getvalue(), "1;2;3\r\n") ! finally: ! csv.unregister_dialect('testC') ! ! def test_bad_dialect(self): ! # Unknown parameter ! self.assertRaises(AttributeError, csv.reader, [], bad_attr = 0) ! # Bad values ! self.assertRaises(TypeError, csv.reader, [], delimiter = None) ! self.assertRaises(TypeError, csv.reader, [], quoting = -1) ! self.assertRaises(TypeError, csv.reader, [], quoting = 100) class TestCsvBase(unittest.TestCase): *************** *** 312,387 **** self.assertEqual(fileobj.getvalue(), expected) - class TestDialectRegistry(unittest.TestCase): - def test_registry_badargs(self): - self.assertRaises(TypeError, csv.list_dialects, None) - self.assertRaises(TypeError, csv.get_dialect, None) - self.assertRaises(csv.Error, csv.get_dialect, "nonesuch") - self.assertRaises(TypeError, csv.unregister_dialect, None) - self.assertRaises(csv.Error, csv.unregister_dialect, "nonesuch") - self.assertRaises(TypeError, csv.register_dialect, None) - self.assertRaises(TypeError, csv.register_dialect, "nonesuch", None) - class bogus: - def __init__(self): - raise KeyError - self.assertRaises(KeyError, csv.register_dialect, "nonesuch", bogus) - - def test_registry(self): - class myexceltsv(csv.excel): - delimiter = "\t" - name = "myexceltsv" - expected_dialects = csv.list_dialects() + [name] - expected_dialects.sort() - csv.register_dialect(name, myexceltsv) - try: - self.failUnless(isinstance(csv.get_dialect(name), myexceltsv)) - got_dialects = csv.list_dialects() - got_dialects.sort() - self.assertEqual(expected_dialects, got_dialects) - finally: - csv.unregister_dialect(name) - - def test_incomplete_dialect(self): - class myexceltsv(csv.Dialect): - delimiter = "\t" - self.assertRaises(csv.Error, myexceltsv) - - def test_dialect_apply(self): - class testA(csv.excel): - delimiter = "\t" - class testB(csv.excel): - delimiter = ":" - class testC(csv.excel): - delimiter = "|" - - csv.register_dialect('testC', testC) - try: - fileobj = StringIO() - writer = csv.writer(fileobj) - writer.writerow([1,2,3]) - self.assertEqual(fileobj.getvalue(), "1,2,3\r\n") - - fileobj = StringIO() - writer = csv.writer(fileobj, testA) - writer.writerow([1,2,3]) - self.assertEqual(fileobj.getvalue(), "1\t2\t3\r\n") - - fileobj = StringIO() - writer = csv.writer(fileobj, dialect=testB()) - writer.writerow([1,2,3]) - self.assertEqual(fileobj.getvalue(), "1:2:3\r\n") - - fileobj = StringIO() - writer = csv.writer(fileobj, dialect='testC') - writer.writerow([1,2,3]) - self.assertEqual(fileobj.getvalue(), "1|2|3\r\n") - - fileobj = StringIO() - writer = csv.writer(fileobj, dialect=testA, delimiter=';') - writer.writerow([1,2,3]) - self.assertEqual(fileobj.getvalue(), "1;2;3\r\n") - finally: - csv.unregister_dialect('testC') - - def _testclasses(): mod = sys.modules[__name__] --- 427,430 ---- From rhettinger@users.sourceforge.net Fri Feb 7 07:26:27 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 06 Feb 2003 23:26:27 -0800 Subject: [Python-checkins] python/dist/src/Modules itertoolsmodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv1779 Modified Files: itertoolsmodule.c Log Message: * Eliminated tuple re-use in imap(). Doing it correctly made the code too hard to read. * Simplified previous changes to izip() to make it easier to read. Index: itertoolsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/itertoolsmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** itertoolsmodule.c 7 Feb 2003 05:32:57 -0000 1.2 --- itertoolsmodule.c 7 Feb 2003 07:26:25 -0000 1.3 *************** *** 638,642 **** PyObject_HEAD PyObject *iters; - PyObject *argtuple; PyObject *func; } imapobject; --- 638,641 ---- *************** *** 647,651 **** imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { ! PyObject *it, *iters, *argtuple, *func; imapobject *lz; int numargs, i; --- 646,650 ---- imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { ! PyObject *it, *iters, *func; imapobject *lz; int numargs, i; *************** *** 662,682 **** return NULL; - argtuple = PyTuple_New(numargs-1); - if (argtuple == NULL) { - Py_DECREF(iters); - return NULL; - } - for (i=1 ; itp_alloc(type, 0); if (lz == NULL) { - Py_DECREF(argtuple); Py_DECREF(iters); return NULL; } lz->iters = iters; - lz->argtuple = argtuple; func = PyTuple_GET_ITEM(args, 0); Py_INCREF(func); --- 674,681 ---- *************** *** 701,705 **** { PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->argtuple); Py_XDECREF(lz->iters); Py_XDECREF(lz->func); --- 689,692 ---- *************** *** 717,725 **** return err; } - if (lz->argtuple) { - err = visit(lz->argtuple, arg); - if (err) - return err; - } if (lz->func) { err = visit(lz->func, arg); --- 704,707 ---- *************** *** 759,795 **** { PyObject *val; ! PyObject *argtuple=lz->argtuple; int numargs, i; numargs = PyTuple_Size(lz->iters); ! if (lz->func == Py_None) { ! argtuple = PyTuple_New(numargs); ! if (argtuple == NULL) ! return NULL; ! for (i=0 ; iiters, i)); ! if (val == NULL) { ! Py_DECREF(argtuple); ! return NULL; ! } ! PyTuple_SET_ITEM(argtuple, i, val); ! } ! return argtuple; ! } else { ! if (argtuple->ob_refcnt > 1) { ! argtuple = PyTuple_New(numargs); ! if (argtuple == NULL) ! return NULL; ! } ! for (i=0 ; iiters, i)); ! if (val == NULL) ! return NULL; ! Py_DECREF(PyTuple_GET_ITEM(argtuple, i)); ! PyTuple_SET_ITEM(argtuple, i, val); } ! return PyObject_Call(lz->func, argtuple, NULL); } } --- 741,766 ---- { PyObject *val; ! PyObject *argtuple; ! PyObject *result; int numargs, i; numargs = PyTuple_Size(lz->iters); ! argtuple = PyTuple_New(numargs); ! if (argtuple == NULL) ! return NULL; ! for (i=0 ; iiters, i)); ! if (val == NULL) { ! Py_DECREF(argtuple); ! return NULL; } ! PyTuple_SET_ITEM(argtuple, i, val); } + if (lz->func == Py_None) + return argtuple; + result = PyObject_Call(lz->func, argtuple, NULL); + Py_DECREF(argtuple); + return result; } *************** *** 1332,1361 **** PyObject *item; - assert(result->ob_refcnt >= 1); if (result->ob_refcnt == 1) { for (i=0 ; i < tuplesize ; i++) { Py_DECREF(PyTuple_GET_ITEM(result, i)); ! PyTuple_SET_ITEM(result, i, NULL); } Py_INCREF(result); } else { - Py_DECREF(result); result = PyTuple_New(tuplesize); if (result == NULL) return NULL; ! Py_INCREF(result); ! lz->result = result; ! } ! assert(lz->result == result); ! assert(result->ob_refcnt == 2); ! ! for (i=0 ; i < tuplesize ; i++) { ! it = PyTuple_GET_ITEM(lz->ittuple, i); ! item = PyIter_Next(it); ! if (item == NULL) { ! Py_DECREF(result); ! return NULL; } - PyTuple_SET_ITEM(result, i, item); } return result; --- 1303,1329 ---- PyObject *item; if (result->ob_refcnt == 1) { for (i=0 ; i < tuplesize ; i++) { + it = PyTuple_GET_ITEM(lz->ittuple, i); + item = PyIter_Next(it); + if (item == NULL) + return NULL; Py_DECREF(PyTuple_GET_ITEM(result, i)); ! PyTuple_SET_ITEM(result, i, item); } Py_INCREF(result); } else { result = PyTuple_New(tuplesize); if (result == NULL) return NULL; ! for (i=0 ; i < tuplesize ; i++) { ! it = PyTuple_GET_ITEM(lz->ittuple, i); ! item = PyIter_Next(it); ! if (item == NULL) { ! Py_DECREF(result); ! return NULL; ! } ! PyTuple_SET_ITEM(result, i, item); } } return result; From fdrake@users.sourceforge.net Fri Feb 7 14:52:23 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Fri, 07 Feb 2003 06:52:23 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.113,1.114 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv22034 Modified Files: whatsnew23.tex Log Message: - make some links into the reference documentation relative for off-line readers - fix some minor typos and markup errors Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.113 retrieving revision 1.114 diff -C2 -d -r1.113 -r1.114 *** whatsnew23.tex 6 Feb 2003 15:14:04 -0000 1.113 --- whatsnew23.tex 7 Feb 2003 14:52:18 -0000 1.114 *************** *** 1,3 **** --- 1,4 ---- \documentclass{howto} + \usepackage{distutils} % $Id$ *************** *** 25,35 **** the new features, but instead provides a convenient overview. For full details, you should refer to the documentation for Python 2.3, ! such as the ! \citetitle[http://www.python.org/doc/2.3/lib/lib.html]{Python Library ! Reference} and the ! \citetitle[http://www.python.org/doc/2.3/ref/ref.html]{Python ! Reference Manual}. If you want to understand the complete ! implementation and design rationale for a change, refer to the PEP for ! a particular new feature. --- 26,33 ---- the new features, but instead provides a convenient overview. For full details, you should refer to the documentation for Python 2.3, ! such as the \citetitle[../lib/lib.html]{Python Library Reference} and ! the \citetitle[../ref/ref.html]{Python Reference Manual}. If you want ! to understand the complete implementation and design rationale for a ! change, refer to the PEP for a particular new feature. *************** *** 527,532 **** is only a partial overview of the \module{logging} package, so please see the \ulink{package's reference ! documentation}{http://www.python.org/dev/doc/devel/lib/module-logging.html} ! for all of the details. Reading \pep{282} will also be helpful. --- 525,530 ---- is only a partial overview of the \module{logging} package, so please see the \ulink{package's reference ! documentation}{../lib/module-logging.html} for all of the details. ! Reading \pep{282} will also be helpful. *************** *** 708,720 **** %====================================================================== ! \section{PEP 301: Package Index and Metadata for Distutils\label{section-pep301}} Support for the long-requested Python catalog makes its first appearance in 2.3. ! The core component is the new Distutil \samp{register} command. ! Running \code{python setup.py register} will collect up the metadata describing a package, such as its name, version, maintainer, ! description, \&c., and sends it to a central catalog server. Currently the catalog can be browsed at \url{http://www.amk.ca/cgi-bin/pypi.cgi}, but it will move to --- 706,719 ---- %====================================================================== ! \section{PEP 301: Package Index and Metadata for ! Distutils\label{section-pep301}} Support for the long-requested Python catalog makes its first appearance in 2.3. ! The core component is the new Distutils \command{register} command. ! Running \code{python setup.py register} will collect the metadata describing a package, such as its name, version, maintainer, ! description, \&c., and send it to a central catalog server. Currently the catalog can be browsed at \url{http://www.amk.ca/cgi-bin/pypi.cgi}, but it will move to *************** *** 723,729 **** To make the catalog a bit more useful, a new optional ! \samp{classifiers} keyword argument has been added to the Distutils \function{setup()} function. A list of ! \citetitle[http://www.tuxedo.org/\%7Eesr/trove/]{Trove}-style strings can be supplied to help classify the software. Here's an example \file{setup.py} with classifiers, written to be compatible --- 722,729 ---- To make the catalog a bit more useful, a new optional ! \var{classifiers} keyword argument has been added to the Distutils \function{setup()} function. A list of ! \ulink{Trove}{http://catb.org/\textasciitilde esr/trove/}-style ! strings can be supplied to help classify the software. Here's an example \file{setup.py} with classifiers, written to be compatible *************** *** 732,749 **** \begin{verbatim} from distutils import core ! kw = ('name': "Quixote", 'version': "0.5.1", 'description': "A highly Pythonic Web application framework", ! ... ! ) ! if (hasattr(core, 'setup_keywords') and ! 'classifiers' in core.setup_keywords): ! kw['classifiers'] = \ ! ['Topic :: Internet :: WWW/HTTP :: Dynamic Content', ! 'Environment :: No Input/Output (Daemon)', ! 'Intended Audience :: Developers'], ! core.setup (**kw) \end{verbatim} --- 732,749 ---- \begin{verbatim} from distutils import core ! kw = {'name': "Quixote", 'version': "0.5.1", 'description': "A highly Pythonic Web application framework", ! # ... ! } ! if ( hasattr(core, 'setup_keywords') and ! 'classifiers' in core.setup_keywords): ! kw['classifiers'] = \ ! ['Topic :: Internet :: WWW/HTTP :: Dynamic Content', ! 'Environment :: No Input/Output (Daemon)', ! 'Intended Audience :: Developers'], ! core.setup(**kw) \end{verbatim} *************** *** 753,757 **** \begin{seealso} ! \seepep{301}{Package Index and Metadata for Distutils}{Written and implemented by Richard Jones.} \end{seealso} --- 753,758 ---- \begin{seealso} ! \seepep{301}{Package Index and Metadata for Distutils}{Written and ! implemented by Richard Jones.} \end{seealso} *************** *** 1080,1084 **** To understand the motivation for this change, read Michele Simionato's article ! \ulink{``Python 2.3 Method Resolution Order''}{http://www.phyast.pitt.edu/~micheles/mro.html}, or read the thread on python-dev starting with the message at \url{http://mail.python.org/pipermail/python-dev/2002-October/029035.html}. --- 1081,1086 ---- To understand the motivation for this change, read Michele Simionato's article ! \ulink{``Python 2.3 Method Resolution Order''} ! {http://www.phyast.pitt.edu/\textasciitilde micheles/mro.html}, or read the thread on python-dev starting with the message at \url{http://mail.python.org/pipermail/python-dev/2002-October/029035.html}. *************** *** 1713,1717 **** For more information, refer to the \ulink{module's reference ! documentation}{http://www.python.org/dev/doc/devel/lib/module-datetime.html}. (Contributed by Tim Peters.) --- 1715,1719 ---- For more information, refer to the \ulink{module's reference ! documentation}{..//lib/module-datetime.html}. (Contributed by Tim Peters.) *************** *** 1787,1791 **** \begin{seealso} ! \seeurl{http://optik.sourceforge.net} {The Optik site has tutorial and reference documentation for \module{optparse}. --- 1789,1793 ---- \begin{seealso} ! \seeurl{http://optik.sourceforge.net/} {The Optik site has tutorial and reference documentation for \module{optparse}. *************** *** 1998,2002 **** Other new platforms now supported by Python include AtheOS ! (\url{http://www.atheos.cx}), GNU/Hurd, and OpenVMS. --- 2000,2004 ---- Other new platforms now supported by Python include AtheOS ! (\url{http://www.atheos.cx/}), GNU/Hurd, and OpenVMS. From gvanrossum@users.sourceforge.net Fri Feb 7 14:59:17 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 07 Feb 2003 06:59:17 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_descr.py,1.177,1.178 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv25256 Modified Files: test_descr.py Log Message: Add __getnewargs__ method to classes that need it. (Yes, this is an incompatibility. I'll document it in PEP 307.) Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.177 retrieving revision 1.178 diff -C2 -d -r1.177 -r1.178 *** test_descr.py 13 Jan 2003 20:13:09 -0000 1.177 --- test_descr.py 7 Feb 2003 14:59:13 -0000 1.178 *************** *** 2699,2702 **** --- 2699,2704 ---- def __new__(cls, a, b): return super(C1, cls).__new__(cls) + def __getnewargs__(self): + return (self.a, self.b) def __init__(self, a, b): self.a = a *************** *** 2709,2712 **** --- 2711,2716 ---- def __new__(cls, a, b, val=0): return super(C2, cls).__new__(cls, val) + def __getnewargs__(self): + return (self.a, self.b, int(self)) def __init__(self, a, b, val=0): self.a = a From jackjansen@users.sourceforge.net Fri Feb 7 15:45:44 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 07 Feb 2003 07:45:44 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac EasyDialogs.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv15762 Modified Files: EasyDialogs.py Log Message: Made AskFile* dialogs movable-modal by default, by providing a dummy eventProc (which simply drops all events on the floor). Also added a method SetDefaultEventProc through which frameworks can set a global event handler (which can still be overridden on a per-call basis with the eventProc argument). Index: EasyDialogs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/EasyDialogs.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** EasyDialogs.py 26 Jan 2003 20:22:18 -0000 1.7 --- EasyDialogs.py 7 Feb 2003 15:45:40 -0000 1.8 *************** *** 592,596 **** --- 592,612 ---- return args, tpwanted + def _dummy_Nav_eventproc(msg, data): + pass + + _default_Nav_eventproc = _dummy_Nav_eventproc + + def SetDefaultEventProc(proc): + global _default_Nav_eventproc + rv = _default_Nav_eventproc + if proc is None: + proc = _dummy_Nav_eventproc + _default_Nav_eventproc = proc + return rv + def AskFileForOpen( + message=None, + typeList=None, + # From here on the order is not documented version=None, defaultLocation=None, *************** *** 601,611 **** actionButtonLabel=None, cancelButtonLabel=None, - message=None, preferenceKey=None, popupExtension=None, ! eventProc=None, previewProc=None, filterProc=None, - typeList=None, wanted=None, multiple=None): --- 617,625 ---- actionButtonLabel=None, cancelButtonLabel=None, preferenceKey=None, popupExtension=None, ! eventProc=_dummy_Nav_eventproc, previewProc=None, filterProc=None, wanted=None, multiple=None): *************** *** 643,646 **** --- 657,663 ---- def AskFileForSave( + message=None, + savedFileName=None, + # From here on the order is not documented version=None, defaultLocation=None, *************** *** 651,659 **** actionButtonLabel=None, cancelButtonLabel=None, - savedFileName=None, - message=None, preferenceKey=None, popupExtension=None, ! eventProc=None, fileType=None, fileCreator=None, --- 668,674 ---- actionButtonLabel=None, cancelButtonLabel=None, preferenceKey=None, popupExtension=None, ! eventProc=_dummy_Nav_eventproc, fileType=None, fileCreator=None, *************** *** 672,677 **** actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel, savedFileName=savedFileName,message=message,preferenceKey=preferenceKey, ! popupExtension=popupExtension,fileType=fileType,fileCreator=fileCreator, ! wanted=wanted,multiple=multiple) try: rr = Nav.NavPutFile(args) --- 687,692 ---- actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel, savedFileName=savedFileName,message=message,preferenceKey=preferenceKey, ! popupExtension=popupExtension,eventProc=eventProc,fileType=fileType, ! fileCreator=fileCreator,wanted=wanted,multiple=multiple) try: rr = Nav.NavPutFile(args) *************** *** 704,707 **** --- 719,724 ---- def AskFolder( + message=None, + # From here on the order is not documented version=None, defaultLocation=None, *************** *** 712,719 **** actionButtonLabel=None, cancelButtonLabel=None, - message=None, preferenceKey=None, popupExtension=None, ! eventProc=None, filterProc=None, wanted=None, --- 729,735 ---- actionButtonLabel=None, cancelButtonLabel=None, preferenceKey=None, popupExtension=None, ! eventProc=_dummy_Nav_eventproc, filterProc=None, wanted=None, From montanaro@users.sourceforge.net Fri Feb 7 15:55:00 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Fri, 07 Feb 2003 07:55:00 -0800 Subject: [Python-checkins] python/dist/src configure,1.279.6.16,1.279.6.17 configure.in,1.288.6.16,1.288.6.17 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv20387 Modified Files: Tag: release22-maint configure configure.in Log Message: backport of a tiny part of patch 557719 - just enough to allow the BUILDEXE Makefile variable to be set properly when doing out-of-tree builds. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.279.6.16 retrieving revision 1.279.6.17 diff -C2 -d -r1.279.6.16 -r1.279.6.17 *** configure 10 Oct 2002 15:26:41 -0000 1.279.6.16 --- configure 7 Feb 2003 15:54:27 -0000 1.279.6.17 *************** *** 1341,1345 **** echo $ac_n "checking for case-insensitive build directory""... $ac_c" 1>&6 echo "configure:1343: checking for case-insensitive build directory" >&5 ! if test -d "python" then echo "$ac_t""yes" 1>&6 --- 1341,1345 ---- echo $ac_n "checking for case-insensitive build directory""... $ac_c" 1>&6 echo "configure:1343: checking for case-insensitive build directory" >&5 ! if test -d "${srcdir}/python" then echo "$ac_t""yes" 1>&6 Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.288.6.16 retrieving revision 1.288.6.17 diff -C2 -d -r1.288.6.16 -r1.288.6.17 *** configure.in 10 Oct 2002 15:26:46 -0000 1.288.6.16 --- configure.in 7 Feb 2003 15:54:52 -0000 1.288.6.17 *************** *** 210,214 **** AC_SUBST(BUILDEXEEXT) AC_MSG_CHECKING(for case-insensitive build directory) ! if test -d "python" then AC_MSG_RESULT(yes) --- 210,214 ---- AC_SUBST(BUILDEXEEXT) AC_MSG_CHECKING(for case-insensitive build directory) ! if test -d "${srcdir}/python" then AC_MSG_RESULT(yes) From gvanrossum@users.sourceforge.net Fri Feb 7 17:03:35 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 07 Feb 2003 09:03:35 -0800 Subject: [Python-checkins] python/nondist/peps pep-0308.txt,NONE,1.1 pep-0000.txt,1.227,1.228 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv30372 Modified Files: pep-0000.txt Added Files: pep-0308.txt Log Message: Add PEP 308: if-then-else expression proposal. --- NEW FILE: pep-0308.txt --- PEP: 308 Title: If-then-else expression Version: $Revision: 1.1 $ Last-Modified: $Date: 2003/02/07 17:03:31 $ Author: Guido van Rossum Status: Active Type: Standards Track Content-Type: text/plain Created: 7-Feb-2003 Post-History: 7-Feb-2003 Introduction Requests for an if-then-else ("ternary") expression keep coming up on comp.lang.python. This PEP contains a concrete proposal of a fairly Pythonic syntax. This is the community's one chance: if this PEP is approved with a clear majority, it will be implemented in Python 2.4. If not, the PEP will be augmented with a summary of the reasons for rejection and the subject better not come up again. While I am the author of this PEP, I am neither in favor nor against this proposal; it is up to the community to decide. If the community can't decide, I'll reject the PEP. Proposal The proposed syntax is as follows: if else This is evaluated like this: - First, is evaluated. - If is true, is evaluated and is the result of the whole thing. - If is false, is evaluated and is the result of the whole thing. Note that at most one of and is evaluated. This is called a "shortcut expression"; it is similar to the way the second operand of 'and' / 'or' is only evaluated if the first operand is true / false. To disambiguate this in the context of other operators, the "if...else" part in the middle acts like a left-associative binary operator with a priority lower than that of "or", and higher than that of "lambda". Examples of how this works out: x if C else y if D else z <==> x if C else (y if D else z) x or y if C else z <==> (x or y) if C else z x if C else y or z <==> x if C else (y or z) lambda: x if C else y <==> lambda: (x if C else y) x if C else lambda: y <==> SyntaxError x if C else y, z <==> (x if C else y), z x, y if C else z <==> x, (y if C else z) Alternatives Many C-derived languages use this syntax: ? : I reject this for several reasons: the colon already has many uses in Python (even though it would actually not be ambiguous, because the question mark requires a matching colon); for people not used to C-derived language, it is hard to understand. Eric Raymond proposed a variant that doesn't have this problem: ? ! While cute, this suffers from the Perlish problem of using arbitrary punctuation with an arbitrary meaning; and it's no easier to understand than the ?: form. If we could live with adding a new keyword, we could use: if then else Apart from the problem of introducing a new keyword for a minor feature, this also suffers from ambiguity at the start of a statement; for example: if verbose then sys.stdout.write("hello\n") else None could be an syntactically correct expression statement, but starts with 'if', which makes the parser believe it is the start of an 'if' statement. To resolve this, the syntax would have to require parentheses, which makes it uglier. However, this form has the advantage of evaluating strictly from left to right (not that that is a requirement for being Pythonic -- list comprehensions don't). Copyright This document has been placed in the public domain. Local Variables: mode: indented-text indent-tabs-mode: nil sentence-end-double-space: t fill-column: 70 End: Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.227 retrieving revision 1.228 diff -C2 -d -r1.227 -r1.228 *** pep-0000.txt 31 Jan 2003 19:12:52 -0000 1.227 --- pep-0000.txt 7 Feb 2003 17:03:29 -0000 1.228 *************** *** 110,113 **** --- 110,114 ---- I 306 How to Change Python's Grammar Hudson S 307 Extensions to the pickle protocol GvR, Peters + S 308 If-then-else expression GvR Finished PEPs (done, implemented in CVS) *************** *** 307,310 **** --- 308,312 ---- I 306 How to Change Python's Grammar Hudson S 307 Extensions to the pickle protocol GvR, Peters + S 308 If-then-else expression GvR SR 666 Reject Foolish Indentation Creighton From montanaro@users.sourceforge.net Fri Feb 7 15:59:34 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Fri, 07 Feb 2003 07:59:34 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.337.2.4.2.57,1.337.2.4.2.58 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv23979 Modified Files: Tag: release22-maint NEWS Log Message: BUILDEXE setting in out-of-tree builds Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.337.2.4.2.57 retrieving revision 1.337.2.4.2.58 diff -C2 -d -r1.337.2.4.2.57 -r1.337.2.4.2.58 *** NEWS 28 Jan 2003 19:40:15 -0000 1.337.2.4.2.57 --- NEWS 7 Feb 2003 15:59:28 -0000 1.337.2.4.2.58 *************** *** 66,69 **** --- 66,72 ---- - SF #667147, fix crash when printing str subclass. + - SF #557719, backported just the tiny fragment necessary to get BUILDEXE + set properly in out-of-tree builds. + What's New in Python 2.2.2 (final) ? Release date: 14-Oct-2002 From gvanrossum@users.sourceforge.net Fri Feb 7 17:30:22 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 07 Feb 2003 09:30:22 -0800 Subject: [Python-checkins] python/dist/src/Lib copy.py,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv11280 Modified Files: copy.py Log Message: Add support for copy_reg.dispatch_table. Rewrote copy() and deepcopy() without avoidable try/except statements; getattr(x, name, None) or dict.get() are much faster than try/except. Index: copy.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** copy.py 6 Feb 2003 22:57:00 -0000 1.34 --- copy.py 7 Feb 2003 17:30:16 -0000 1.35 *************** *** 49,56 **** """ - # XXX need to support copy_reg here too... - import types ! from copy_reg import _better_reduce class Error(Exception): --- 49,54 ---- """ import types ! from copy_reg import _better_reduce, dispatch_table class Error(Exception): *************** *** 71,93 **** """ ! try: ! copierfunction = _copy_dispatch[type(x)] ! except KeyError: ! try: ! copier = x.__copy__ ! except AttributeError: ! try: ! reductor = x.__class__.__reduce__ ! if reductor == object.__reduce__: ! reductor = _better_reduce ! except AttributeError: ! raise Error("un(shallow)copyable object of type %s" % type(x)) ! else: ! y = _reconstruct(x, reductor(x), 0) ! else: ! y = copier() ! else: ! y = copierfunction(x) ! return y --- 69,91 ---- """ ! cls = type(x) ! ! copier = _copy_dispatch.get(cls) ! if copier: ! return copier(x) ! ! copier = getattr(cls, "__copy__", None) ! if copier: ! return copier(x) ! ! reductor = dispatch_table.get(cls) ! if not reductor: ! reductor = getattr(cls, "__reduce__", None) ! if reductor == object.__reduce__: ! reductor = _better_reduce ! elif not reductor: ! raise Error("un(shallow)copyable object of type %s" % cls) ! ! return _reconstruct(x, reductor(x), 0) *************** *** 154,158 **** del d ! def deepcopy(x, memo = None): """Deep copy operation on arbitrary Python objects. --- 152,156 ---- del d ! def deepcopy(x, memo=None, _nil=[]): """Deep copy operation on arbitrary Python objects. *************** *** 162,194 **** if memo is None: memo = {} d = id(x) ! if d in memo: ! return memo[d] ! try: ! copierfunction = _deepcopy_dispatch[type(x)] ! except KeyError: try: ! issc = issubclass(type(x), type) ! except TypeError: issc = 0 if issc: ! y = _deepcopy_dispatch[type](x, memo) else: ! try: ! copier = x.__deepcopy__ ! except AttributeError: ! try: ! reductor = x.__class__.__reduce__ ! if reductor == object.__reduce__: ! reductor = _better_reduce ! except AttributeError: ! raise Error("un(shallow)copyable object of type %s" % ! type(x)) ! else: ! y = _reconstruct(x, reductor(x), 1, memo) ! else: ! y = copier(memo) ! else: ! y = copierfunction(x, memo) memo[d] = y _keep_alive(x, memo) # Make sure x lives at least as long as d --- 160,196 ---- if memo is None: memo = {} + d = id(x) ! y = memo.get(d, _nil) ! if y is not _nil: ! return y ! ! cls = type(x) ! ! copier = _deepcopy_dispatch.get(cls) ! if copier: ! y = copier(x, memo) ! else: try: ! issc = issubclass(cls, type) ! except TypeError: # cls is not a class (old Boost; see SF #502085) issc = 0 if issc: ! copier = _deepcopy_atomic else: ! copier = getattr(cls, "__deepcopy__", None) ! ! if copier: ! y = copier(x, memo) ! else: ! reductor = dispatch_table.get(cls) ! if not reductor: ! reductor = getattr(cls, "__reduce__", None) ! if reductor == object.__reduce__: ! reductor = _better_reduce ! elif not reductor: ! raise Error("un(deep)copyable object of type %s" % cls) ! y = _reconstruct(x, reductor(x), 1, memo) ! memo[d] = y _keep_alive(x, memo) # Make sure x lives at least as long as d *************** *** 381,385 **** for key, value in state.iteritems(): setattr(self, key, value) ! def __deepcopy__(self, memo = None): new = self.__class__(deepcopy(self.arg, memo)) new.a = self.a --- 383,387 ---- for key, value in state.iteritems(): setattr(self, key, value) ! def __deepcopy__(self, memo=None): new = self.__class__(deepcopy(self.arg, memo)) new.a = self.a From gvanrossum@users.sourceforge.net Fri Feb 7 17:30:23 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 07 Feb 2003 09:30:23 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_copy.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv11280/test Modified Files: test_copy.py Log Message: Add support for copy_reg.dispatch_table. Rewrote copy() and deepcopy() without avoidable try/except statements; getattr(x, name, None) or dict.get() are much faster than try/except. Index: test_copy.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_copy.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_copy.py 6 Feb 2003 21:25:12 -0000 1.4 --- test_copy.py 7 Feb 2003 17:30:18 -0000 1.5 *************** *** 3,6 **** --- 3,7 ---- import sys import copy + import copy_reg import unittest *************** *** 33,36 **** --- 34,50 ---- self.assertEqual(y.foo, x.foo) + def test_copy_registry(self): + class C(object): + def __new__(cls, foo): + obj = object.__new__(cls) + obj.foo = foo + return obj + def pickle_C(obj): + return (C, (obj.foo,)) + x = C(42) + self.assertRaises(TypeError, copy.copy, x) + copy_reg.pickle(C, pickle_C, C) + y = copy.copy(x) + def test_copy_reduce(self): class C(object): *************** *** 182,185 **** --- 196,212 ---- self.assertEqual(y.__class__, x.__class__) self.assertEqual(y.foo, x.foo) + + def test_deepcopy_registry(self): + class C(object): + def __new__(cls, foo): + obj = object.__new__(cls) + obj.foo = foo + return obj + def pickle_C(obj): + return (C, (obj.foo,)) + x = C(42) + self.assertRaises(TypeError, copy.deepcopy, x) + copy_reg.pickle(C, pickle_C, C) + y = copy.deepcopy(x) def test_deepcopy_reduce(self): From gvanrossum@users.sourceforge.net Fri Feb 7 17:53:26 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 07 Feb 2003 09:53:26 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_copy.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv27206/test Modified Files: test_copy.py Log Message: Somehow, copy() of a classic class object was handled atomically, but deepcopy() didn't support this at all. I don't see any reason for this, so I'm adding ClassType to the set of types that are deep-copied atomically. Index: test_copy.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_copy.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_copy.py 7 Feb 2003 17:30:18 -0000 1.5 --- test_copy.py 7 Feb 2003 17:53:23 -0000 1.6 *************** *** 240,244 **** tests = [None, 42, 2L**100, 3.14, True, False, 1j, "hello", u"hello\u1234", f.func_code, ! NewStyle, xrange(10)] for x in tests: self.assert_(copy.deepcopy(x) is x, `x`) --- 240,244 ---- tests = [None, 42, 2L**100, 3.14, True, False, 1j, "hello", u"hello\u1234", f.func_code, ! NewStyle, xrange(10), Classic] for x in tests: self.assert_(copy.deepcopy(x) is x, `x`) From gvanrossum@users.sourceforge.net Fri Feb 7 17:53:26 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 07 Feb 2003 09:53:26 -0800 Subject: [Python-checkins] python/dist/src/Lib copy.py,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv27206 Modified Files: copy.py Log Message: Somehow, copy() of a classic class object was handled atomically, but deepcopy() didn't support this at all. I don't see any reason for this, so I'm adding ClassType to the set of types that are deep-copied atomically. Index: copy.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** copy.py 7 Feb 2003 17:30:16 -0000 1.35 --- copy.py 7 Feb 2003 17:53:20 -0000 1.36 *************** *** 221,224 **** --- 221,225 ---- d[types.TypeType] = _deepcopy_atomic d[types.XRangeType] = _deepcopy_atomic + d[types.ClassType] = _deepcopy_atomic def _deepcopy_list(x, memo): From gvanrossum@users.sourceforge.net Fri Feb 7 18:11:34 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 07 Feb 2003 10:11:34 -0800 Subject: [Python-checkins] python/nondist/peps pep-0307.txt,1.14,1.15 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv5765 Modified Files: pep-0307.txt Log Message: Add posting-date. Add note about the copy module. Remove TBD -- this PEP is complete AFAIAC. Index: pep-0307.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0307.txt,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** pep-0307.txt 6 Feb 2003 20:38:30 -0000 1.14 --- pep-0307.txt 7 Feb 2003 18:11:29 -0000 1.15 *************** *** 8,12 **** Content-Type: text/plain Created: 31-Jan-2003 ! Post-History: None --- 8,12 ---- Content-Type: text/plain Created: 31-Jan-2003 ! Post-History: 7-Feb-2003 *************** *** 600,606 **** ! TBD ! The rest of this PEP is still under construction! --- 600,646 ---- ! The copy module ! Traditionally, the copy module has supported an extended subset of ! the pickling APIs for customizing the copy() and deepcopy() ! operations. ! ! In particular, besides checking for a __copy__ or __deepcopy__ ! method, copy() and deepcopy() have always looked for __reduce__, ! and for classic classes, have looked for __getinitargs__, ! __getstate__ and __setstate__. ! ! In Python 2.2, the default __reduce__ inherited from 'object' made ! copying simple new-style classes possible, but slots and various ! other special cases were not covered. ! ! In Python 2.3, several changes are made to the copy module: ! ! - The four- and five-argument return values of __reduce__ are ! supported. ! ! - Before looking for a __reduce__ method, the ! copy_reg.dispatch_table is consulted, just like for pickling. ! ! - When the __reduce__ method is inherited from object, it is ! (unconditionally) replaced by a better one that uses the same ! APIs as pickle protocol 2: __getnewargs__, __getstate__, and ! __setstate__, handling list and dict subclasses, and handling ! slots. ! ! As a consequence of the latter change, certain new-style classes ! that were copyable under Python 2.2 are not copyable under Python ! 2.3. (These classes are also not picklable using pickle protocol ! 2.) A minimal example of such a class: ! ! class C(object): ! def __new__(cls, a): ! return object.__new__(cls) ! ! The problem only occurs when __new__ is overridden and has at ! least one mandatory argument in addition to the class argument. ! ! To fix this, a __getnewargs__ method should be added that returns ! the appropriate argument tuple (excluding the class). From gvanrossum@users.sourceforge.net Fri Feb 7 19:30:20 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 07 Feb 2003 11:30:20 -0800 Subject: [Python-checkins] python/nondist/peps pep-0307.txt,1.15,1.16 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv10902 Modified Files: pep-0307.txt Log Message: Typo found by Aahz. Index: pep-0307.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0307.txt,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** pep-0307.txt 7 Feb 2003 18:11:29 -0000 1.15 --- pep-0307.txt 7 Feb 2003 19:30:15 -0000 1.16 *************** *** 202,206 **** primarily used for dict subclasses, but may be used by other classes as long as they implement ! __settitem__. Note: in Python 2.2 and before, when using cPickle, state would be --- 202,206 ---- primarily used for dict subclasses, but may be used by other classes as long as they implement ! __setitem__. Note: in Python 2.2 and before, when using cPickle, state would be From nnorwitz@users.sourceforge.net Fri Feb 7 19:44:58 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 07 Feb 2003 11:44:58 -0800 Subject: [Python-checkins] python/dist/src/Modules mmapmodule.c,2.42,2.43 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv15924/Modules Modified Files: mmapmodule.c Log Message: SF patch #682514, mmapmodule.c write fix for LP64 executables Make length an int so we get the right value from PyArg_ParseTuple(args, "s#", &str, &length) Will backport. Index: mmapmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mmapmodule.c,v retrieving revision 2.42 retrieving revision 2.43 diff -C2 -d -r2.42 -r2.43 *** mmapmodule.c 10 Jan 2003 20:52:15 -0000 2.42 --- mmapmodule.c 7 Feb 2003 19:44:56 -0000 2.43 *************** *** 293,297 **** PyObject *args) { ! long length; char *data; --- 293,297 ---- PyObject *args) { ! int length; char *data; From nnorwitz@users.sourceforge.net Fri Feb 7 19:46:47 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 07 Feb 2003 11:46:47 -0800 Subject: [Python-checkins] python/dist/src/Modules mmapmodule.c,2.35.6.4,2.35.6.5 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv17096/Modules Modified Files: Tag: release22-maint mmapmodule.c Log Message: SF patch #682514, mmapmodule.c write fix for LP64 executables Make length an int so we get the right value from PyArg_ParseTuple(args, "s#", &str, &length) Index: mmapmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mmapmodule.c,v retrieving revision 2.35.6.4 retrieving revision 2.35.6.5 diff -C2 -d -r2.35.6.4 -r2.35.6.5 *** mmapmodule.c 10 Jan 2003 21:02:40 -0000 2.35.6.4 --- mmapmodule.c 7 Feb 2003 19:46:44 -0000 2.35.6.5 *************** *** 293,297 **** PyObject *args) { ! long length; char *data; --- 293,297 ---- PyObject *args) { ! int length; char *data; From akuchling@users.sourceforge.net Fri Feb 7 20:22:36 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Fri, 07 Feb 2003 12:22:36 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.114,1.115 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv1669 Modified Files: whatsnew23.tex Log Message: Update URL Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.114 retrieving revision 1.115 diff -C2 -d -r1.114 -r1.115 *** whatsnew23.tex 7 Feb 2003 14:52:18 -0000 1.114 --- whatsnew23.tex 7 Feb 2003 20:22:33 -0000 1.115 *************** *** 1082,1086 **** read Michele Simionato's article \ulink{``Python 2.3 Method Resolution Order''} ! {http://www.phyast.pitt.edu/\textasciitilde micheles/mro.html}, or read the thread on python-dev starting with the message at \url{http://mail.python.org/pipermail/python-dev/2002-October/029035.html}. --- 1082,1086 ---- read Michele Simionato's article \ulink{``Python 2.3 Method Resolution Order''} ! {http://www.python.org/2.3/mro.html}, or read the thread on python-dev starting with the message at \url{http://mail.python.org/pipermail/python-dev/2002-October/029035.html}. From montanaro@users.sourceforge.net Fri Feb 7 20:18:50 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Fri, 07 Feb 2003 12:18:50 -0800 Subject: [Python-checkins] python/nondist/peps pep-0308.txt,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv31913 Modified Files: pep-0308.txt Log Message: explain why adding a new builtin won't work. Index: pep-0308.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0308.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pep-0308.txt 7 Feb 2003 17:03:31 -0000 1.1 --- pep-0308.txt 7 Feb 2003 20:18:45 -0000 1.2 *************** *** 99,102 **** --- 99,111 ---- is a requirement for being Pythonic -- list comprehensions don't). + Many people suggest adding a new builtin instead of extending the + syntax of the language, e.g.: + + ifelse(condition, expression1, expression2) + + This won't work the way a syntax extension will because both + expression1 and expression2 must be evaluated before the function + is called. There's no way to short-circuit the expression + evaluation. Copyright From tim_one@users.sourceforge.net Fri Feb 7 20:48:05 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 07 Feb 2003 12:48:05 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.157,1.158 test_datetime.py,1.112,1.113 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv10667 Modified Files: datetime.py test_datetime.py Log Message: Comparison for timedelta, time, date and datetime objects: rewrote to use rich comparisons. __eq__ and __ne__ no longer complain if they don't know how to compare to the other thing. If no meaningful way to compare is known, saying "not equal" is sensible. This allows things like if adatetime in some_sequence: and somedict[adatetime] = whatever to work as expected even if some_sequence contains non-datetime objects, or somedict non-datetime keys, because they only call __eq__. It still complains (raises TypeError) for mixed-type comparisons in contexts that require a total ordering, such as list.sort(), use as a key in a BTree-based data structure, and cmp(). Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.157 retrieving revision 1.158 diff -C2 -d -r1.157 -r1.158 *** datetime.py 1 Feb 2003 03:02:33 -0000 1.157 --- datetime.py 7 Feb 2003 20:47:58 -0000 1.158 *************** *** 287,290 **** --- 287,318 ---- raise TypeError("tzinfo argument must be None or of a tzinfo subclass") + + # Notes on comparison: In general, datetime module comparison operators raise + # TypeError when they don't know how to do a comparison themself. If they + # returned NotImplemented instead, comparison could (silently) fall back to + # the default compare-objects-by-comparing-their-memory-addresses strategy, + # and that's not helpful. There are two exceptions: + # + # 1. For date and datetime, if the other object has a "timetuple" attr, + # NotImplemented is returned. This is a hook to allow other kinds of + # datetime-like objects a chance to intercept the comparison. + # + # 2. Else __eq__ and __ne__ return False and True, respectively. This is + # so opertaions like + # + # x == y + # x != y + # x in sequence + # x not in sequence + # dict[x] = y + # + # don't raise annoying TypeErrors just because a datetime object + # is part of a heterogeneous collection. If there's no known way to + # compare X to a datetime, saying they're not equal is reasonable. + + def _cmperror(x, y): + raise TypeError("can't compare '%s' to '%s'" % ( + type(x).__name__, type(y).__name__)) + # This is a start at a struct tm workalike. Goals: # *************** *** 597,604 **** __floordiv__ = __div__ ! def __cmp__(self, other): ! if not isinstance(other, timedelta): ! raise TypeError, ("can't compare timedelta to %s instance" % ! type(other).__name__) return cmp(self.__getstate(), other.__getstate()) --- 625,668 ---- __floordiv__ = __div__ ! # Comparisons. ! ! def __eq__(self, other): ! if isinstance(other, timedelta): ! return self.__cmp(other) == 0 ! else: ! return False ! ! def __ne__(self, other): ! if isinstance(other, timedelta): ! return self.__cmp(other) != 0 ! else: ! return True ! ! def __le__(self, other): ! if isinstance(other, timedelta): ! return self.__cmp(other) <= 0 ! else: ! _cmperror(self, other) ! ! def __lt__(self, other): ! if isinstance(other, timedelta): ! return self.__cmp(other) < 0 ! else: ! _cmperror(self, other) ! ! def __ge__(self, other): ! if isinstance(other, timedelta): ! return self.__cmp(other) >= 0 ! else: ! _cmperror(self, other) ! ! def __gt__(self, other): ! if isinstance(other, timedelta): ! return self.__cmp(other) > 0 ! else: ! _cmperror(self, other) ! ! def __cmp(self, other): ! assert isinstance(other, timedelta) return cmp(self.__getstate(), other.__getstate()) *************** *** 764,778 **** return date(year, month, day) ! def __cmp__(self, other): ! "Three-way comparison." if isinstance(other, date): ! y, m, d = self.__year, self.__month, self.__day ! y2, m2, d2 = other.__year, other.__month, other.__day ! return cmp((y, m, d), (y2, m2, d2)) elif hasattr(other, "timetuple"): return NotImplemented else: ! raise TypeError, ("can't compare date to %s instance" % ! type(other).__name__) def __hash__(self): --- 828,886 ---- return date(year, month, day) ! # Comparisons. ! ! def __eq__(self, other): if isinstance(other, date): ! return self.__cmp(other) == 0 elif hasattr(other, "timetuple"): return NotImplemented else: ! return False ! ! def __ne__(self, other): ! if isinstance(other, date): ! return self.__cmp(other) != 0 ! elif hasattr(other, "timetuple"): ! return NotImplemented ! else: ! return True ! ! def __le__(self, other): ! if isinstance(other, date): ! return self.__cmp(other) <= 0 ! elif hasattr(other, "timetuple"): ! return NotImplemented ! else: ! _cmperror(self, other) ! ! def __lt__(self, other): ! if isinstance(other, date): ! return self.__cmp(other) < 0 ! elif hasattr(other, "timetuple"): ! return NotImplemented ! else: ! _cmperror(self, other) ! ! def __ge__(self, other): ! if isinstance(other, date): ! return self.__cmp(other) >= 0 ! elif hasattr(other, "timetuple"): ! return NotImplemented !