[Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.71,2.72

Guido van Rossum guido@cnri.reston.va.us
Mon, 13 Mar 2000 11:27:10 -0500 (EST)


Update of /projects/cvsroot/python/dist/src/Objects
In directory eric:/projects/python/develop/guido/src/Objects

Modified Files:
	fileobject.c 
Log Message:
Checking in the new, improve file.writelines() code.

This (1) avoids thread unsafety whereby another thread could zap the
list while we were using it, and (2) now supports writing arbitrary
sequences of strings.


Index: fileobject.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Objects/fileobject.c,v
retrieving revision 2.71
retrieving revision 2.72
diff -C2 -r2.71 -r2.72
*** fileobject.c	2000/03/10 22:55:18	2.71
--- fileobject.c	2000/03/13 16:27:06	2.72
***************
*** 891,928 ****
  	PyObject *args;
  {
! 	int i, n;
  	if (f->f_fp == NULL)
  		return err_closed();
! 	if (args == NULL || !PyList_Check(args)) {
  		PyErr_SetString(PyExc_TypeError,
! 			   "writelines() requires list of strings");
  		return NULL;
  	}
! 	n = PyList_Size(args);
! 	f->f_softspace = 0;
! 	Py_BEGIN_ALLOW_THREADS
! 	errno = 0;
! 	for (i = 0; i < n; i++) {
! 		PyObject *line = PyList_GetItem(args, i);
! 		int len;
! 		int nwritten;
! 		if (!PyString_Check(line)) {
! 			Py_BLOCK_THREADS
! 			PyErr_SetString(PyExc_TypeError,
! 				   "writelines() requires list of strings");
  			return NULL;
  		}
! 		len = PyString_Size(line);
! 		nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
! 		if (nwritten != len) {
! 			Py_BLOCK_THREADS
! 			PyErr_SetFromErrno(PyExc_IOError);
! 			clearerr(f->f_fp);
! 			return NULL;
  		}
  	}
! 	Py_END_ALLOW_THREADS
  	Py_INCREF(Py_None);
! 	return Py_None;
  }
  
--- 891,982 ----
  	PyObject *args;
  {
! #define CHUNKSIZE 1000
! 	PyObject *list, *line;
! 	PyObject *result;
! 	int i, j, index, len, nwritten, islist;
! 
  	if (f->f_fp == NULL)
  		return err_closed();
! 	if (args == NULL || !PySequence_Check(args)) {
  		PyErr_SetString(PyExc_TypeError,
! 			   "writelines() requires sequence of strings");
  		return NULL;
  	}
! 	islist = PyList_Check(args);
! 
! 	/* Strategy: slurp CHUNKSIZE lines into a private list,
! 	   checking that they are all strings, then write that list
! 	   without holding the interpreter lock, then come back for more. */
! 	index = 0;
! 	if (islist)
! 		list = NULL;
! 	else {
! 		list = PyList_New(CHUNKSIZE);
! 		if (list == NULL)
  			return NULL;
+ 	}
+ 	result = NULL;
+ 
+ 	for (;;) {
+ 		if (islist) {
+ 			Py_XDECREF(list);
+ 			list = PyList_GetSlice(args, index, index+CHUNKSIZE);
+ 			if (list == NULL)
+ 				return NULL;
+ 			j = PyList_GET_SIZE(list);
  		}
! 		else {
! 			for (j = 0; j < CHUNKSIZE; j++) {
! 				line = PySequence_GetItem(args, index+j);
! 				if (line == NULL) {
! 					if (PyErr_ExceptionMatches(
! 						PyExc_IndexError))
! 					{
! 						PyErr_Clear();
! 						break;
! 					}
! 					/* Some other error occurred.
! 					   XXX We may lose some output. */
! 					goto error;
! 				}
! 				if (!PyString_Check(line)) {
! 					Py_DECREF(line);
! 					PyErr_SetString(PyExc_TypeError,
! 				 "writelines() requires sequences of strings");
! 					goto error;
! 				}
! 				PyList_SetItem(list, j, line);
! 			}
! 		}
! 		if (j == 0)
! 			break;
! 
! 		Py_BEGIN_ALLOW_THREADS
! 		f->f_softspace = 0;
! 		errno = 0;
! 		for (i = 0; i < j; i++) {
! 			line = PyList_GET_ITEM(list, i);
! 			len = PyString_GET_SIZE(line);
! 			nwritten = fwrite(PyString_AS_STRING(line),
! 					  1, len, f->f_fp);
! 			if (nwritten != len) {
! 				Py_BLOCK_THREADS
! 				PyErr_SetFromErrno(PyExc_IOError);
! 				clearerr(f->f_fp);
! 				goto error;
! 			}
  		}
+ 		Py_END_ALLOW_THREADS
+ 
+ 		if (j < CHUNKSIZE)
+ 			break;
+ 		index += CHUNKSIZE;
  	}
! 
  	Py_INCREF(Py_None);
! 	result = Py_None;
!   error:
! 	Py_XDECREF(list);
! 	return result;
  }
  



Return-Path: <mal@lemburg.com>
Delivered-To: python-checkins@python.org
Received: from starship.skyport.net (starship.skyport.net [216.169.96.18])
	by dinsdale.python.org (Postfix) with ESMTP id 80EA81CD0D
	for <python-checkins@python.org>; Mon, 13 Mar 2000 18:13:14 -0500 (EST)
Received: from lemburg.com (p3E9EEA36.dip.t-dialin.net [62.158.234.54])
	by starship.skyport.net (8.8.8/8.8.8) with ESMTP id SAA18611;
	Mon, 13 Mar 2000 18:13:37 -0500
Message-ID: <38CD76D6.EE398B6B@lemburg.com>
Date: Tue, 14 Mar 2000 00:16:38 +0100
From: "M.-A. Lemburg" <mal@lemburg.com>
Reply-To: mal@lemburg.com
Organization: IKDS M.-A. Lemburg -- http://www.lemburg.com/
X-Mailer: Mozilla 4.61 [en] (X11; I; Linux 2.2.10 i586)
X-Accept-Language: en
MIME-Version: 1.0
To: python-checkins@python.org
References: <20000313170038.D25391CD68@dinsdale.python.org>
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Subject: [Python-checkins] Re: Python-checkins digest, Vol 1 #390 - 10 msgs
Sender: python-checkins-admin@python.org
Errors-To: python-checkins-admin@python.org
X-BeenThere: python-checkins@python.org
X-Mailman-Version: 1.2 (beta 1)
Precedence: bulk
List-Id: Check-in messages from the Python maintainers <python-checkins.python.org>

> Today's Topics:
> 
>   1. CVS: python/dist/src/Tools/idle PyParse.py,1.5,1.6 (Guido van Rossum)
>   2. CVS: python/dist/src Makefile.in,1.83,1.84 (Guido van Rossum)
>   3. CVS: python/dist/src/Doc/lib libos.tex,1.33.2.2,1.33.2.3 (Fred L. Drake)
>   4. CVS: python/dist/src/Objects listobject.c,2.65,2.66 (Guido van Rossum)
>   5. CVS: python/dist/src/Objects unicodeobject.c,2.1,2.2 (Guido van Rossum)

The corresponding patches for Include/unicodeobject.h and
Lib/test/test_unicode.py seem to be missing from this list.

>   6. CVS: python/dist/src/Objects stringobject.c,2.58,2.59 (Guido van Rossum)
>   7. CVS: python/dist/src/Python traceback.c,2.24,2.25 (Guido van Rossum)
>   8. CVS: python/dist/src/Objects dictobject.c,2.49,2.50 frameobject.c,2.37,2.38 listobject.c,2.66,2.67 object.c,2.63,2.64 tupleobject.c,2.29,2.30 (Guido van Rossum)
>   9. CVS: python/dist/src/Include object.h,2.50,2.51 (Guido van Rossum)
>   10. CVS: python/dist/src/Objects fileobject.c,2.71,2.72 (Guido van Rossum)

-- 
Marc-Andre Lemburg
______________________________________________________________________
Business:                                      http://www.lemburg.com/
Python Pages:                           http://www.lemburg.com/python/


Return-Path: <mal@lemburg.com>
Delivered-To: python-checkins@python.org
Received: from starship.skyport.net (starship.skyport.net [216.169.96.18])
	by dinsdale.python.org (Postfix) with ESMTP id 1D9F01CD82
	for <python-checkins@python.org>; Mon, 13 Mar 2000 18:09:15 -0500 (EST)
Received: from lemburg.com (p3E9EEA36.dip.t-dialin.net [62.158.234.54])
	by starship.skyport.net (8.8.8/8.8.8) with ESMTP id SAA18495;
	Mon, 13 Mar 2000 18:09:42 -0500
Message-ID: <38CD75AE.726A85DC@lemburg.com>
Date: Tue, 14 Mar 2000 00:11:42 +0100
From: "M.-A. Lemburg" <mal@lemburg.com>
Reply-To: mal@lemburg.com
Organization: IKDS M.-A. Lemburg -- http://www.lemburg.com/
X-Mailer: Mozilla 4.61 [en] (X11; I; Linux 2.2.10 i586)
X-Accept-Language: en
MIME-Version: 1.0
To: python-checkins@python.org
References: <20000313170038.D25391CD68@dinsdale.python.org>
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Subject: [Python-checkins] Re: Python-checkins digest, Vol 1 #390 - 10 msgs
Sender: python-checkins-admin@python.org
Errors-To: python-checkins-admin@python.org
X-BeenThere: python-checkins@python.org
X-Mailman-Version: 1.2 (beta 1)
Precedence: bulk
List-Id: Check-in messages from the Python maintainers <python-checkins.python.org>

> *** stringobject.c      2000/03/10 22:55:18     2.58
> --- stringobject.c      2000/03/13 15:56:08     2.59
> ***************
> *** 390,394 ****
>         register char *s, *end;
>         register char c;
> !       if (!PyString_Check(el) || PyString_Size(el) != 1) {
>                 PyErr_SetString(PyExc_TypeError,
>                                 "string member test needs char left operand");
> --- 390,396 ----
>         register char *s, *end;
>         register char c;
> !       if (!PyString_Check(el))
> !               return PyUnicode_Contains(a, el);
> !       if (PyString_Size(el) != 1) {
>                 PyErr_SetString(PyExc_TypeError,
>                                 "string member test needs char left operand");
> ***************
> *** 1576,1580 ****
>                 return NULL;
>   
> !       if (repl_len <= 0) {
>                 PyErr_SetString(PyExc_ValueError, "empty replacement string");
>                 return NULL;
> --- 1578,1582 ----
>                 return NULL;
>   
> !       if (sub_len <= 0) {
>                 PyErr_SetString(PyExc_ValueError, "empty replacement string");
>                 return NULL;
> 

It should read "empty pattern string".

-- 
Marc-Andre Lemburg
______________________________________________________________________
Business:                                      http://www.lemburg.com/
Python Pages:                           http://www.lemburg.com/python/