X Tutup
Skip to content

Commit da5b8f2

Browse files
committed
Rip out the file object's implementation.
Fixed test_import.py while I was at it. However, there's still a problem in import.c -- get_file() can leak a FILE struct (not a file descriptor though). I'm not sure how to fix this; closing the FILE* closes the file descriptor, and that's the wrong thing to do when there's still a Python file object keeping the file descriptor open. I also would rather not mess with dup(), as it won't port to Windows.
1 parent 2d5c219 commit da5b8f2

File tree

14 files changed

+119
-2550
lines changed

14 files changed

+119
-2550
lines changed

Include/fileobject.h

Lines changed: 4 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,25 @@
1-
2-
/* File object interface */
1+
/* File object interface (what's left of it -- see io.py) */
32

43
#ifndef Py_FILEOBJECT_H
54
#define Py_FILEOBJECT_H
65
#ifdef __cplusplus
76
extern "C" {
87
#endif
98

10-
typedef struct {
11-
PyObject_HEAD
12-
FILE *f_fp;
13-
PyObject *f_name;
14-
PyObject *f_mode;
15-
int (*f_close)(FILE *);
16-
int f_binary; /* Flag which indicates whether the file is
17-
open in binary (1) or text (0) mode */
18-
char* f_buf; /* Allocated readahead buffer */
19-
char* f_bufend; /* Points after last occupied position */
20-
char* f_bufptr; /* Current buffer position */
21-
char *f_setbuf; /* Buffer for setbuf(3) and setvbuf(3) */
22-
int f_univ_newline; /* Handle any newline convention */
23-
int f_newlinetypes; /* Types of newlines seen */
24-
int f_skipnextlf; /* Skip next \n */
25-
PyObject *f_encoding;
26-
PyObject *weakreflist; /* List of weak references */
27-
} PyFileObject;
28-
29-
PyAPI_DATA(PyTypeObject) PyFile_Type;
30-
31-
#define PyFile_Check(op) PyObject_TypeCheck(op, &PyFile_Type)
32-
#define PyFile_CheckExact(op) ((op)->ob_type == &PyFile_Type)
9+
#define PY_STDIOTEXTMODE "b"
3310

34-
PyAPI_FUNC(PyObject *) PyFile_FromString(char *, char *);
35-
PyAPI_FUNC(void) PyFile_SetBufSize(PyObject *, int);
36-
PyAPI_FUNC(int) PyFile_SetEncoding(PyObject *, const char *);
37-
PyAPI_FUNC(PyObject *) PyFile_FromFile(FILE *, char *, char *,
38-
int (*)(FILE *));
39-
PyAPI_FUNC(FILE *) PyFile_AsFile(PyObject *);
40-
PyAPI_FUNC(PyObject *) PyFile_Name(PyObject *);
11+
PyAPI_FUNC(PyObject *) PyFile_FromFile(FILE *, char *, char *, int (*)(FILE*));
4112
PyAPI_FUNC(PyObject *) PyFile_GetLine(PyObject *, int);
4213
PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int);
4314
PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *);
4415
PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *);
16+
PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
4517

4618
/* The default encoding used by the platform file system APIs
4719
If non-NULL, this is different than the default encoding for strings
4820
*/
4921
PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding;
5022

51-
/* Routines to replace fread() and fgets() which accept any of \r, \n
52-
or \r\n as line terminators.
53-
*/
54-
#define PY_STDIOTEXTMODE "b"
55-
char *Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
56-
size_t Py_UniversalNewlineFread(char *, size_t, FILE *, PyObject *);
57-
58-
/* A routine to do sanity checking on the file mode string. returns
59-
non-zero on if an exception occurred
60-
*/
61-
int _PyFile_SanitizeMode(char *mode);
62-
6323
#ifdef __cplusplus
6424
}
6525
#endif

Include/sysmodule.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ extern "C" {
99

1010
PyAPI_FUNC(PyObject *) PySys_GetObject(char *);
1111
PyAPI_FUNC(int) PySys_SetObject(char *, PyObject *);
12-
PyAPI_FUNC(FILE *) PySys_GetFile(char *, FILE *);
1312
PyAPI_FUNC(void) PySys_SetArgv(int, char **);
1413
PyAPI_FUNC(void) PySys_SetPath(char *);
1514

Modules/_cursesmodule.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,12 +1287,13 @@ PyCursesWindow_PutWin(PyCursesWindowObject *self, PyObject *args)
12871287

12881288
if (!PyArg_ParseTuple(args, "O;fileobj", &temp))
12891289
return NULL;
1290-
if (!PyFile_Check(temp)) {
1291-
PyErr_SetString(PyExc_TypeError, "argument must be a file object");
1292-
return NULL;
1293-
}
1290+
PyErr_SetString(PyExc_TypeError, "argument must be a file object");
1291+
return NULL;
1292+
1293+
#if 0
12941294
return PyCursesCheckERR(putwin(self->win, PyFile_AsFile(temp)),
12951295
"putwin");
1296+
#endif
12961297
}
12971298

12981299
static PyObject *
@@ -1748,11 +1749,10 @@ PyCurses_GetWin(PyCursesWindowObject *self, PyObject *temp)
17481749

17491750
PyCursesInitialised
17501751

1751-
if (!PyFile_Check(temp)) {
1752-
PyErr_SetString(PyExc_TypeError, "argument must be a file object");
1753-
return NULL;
1754-
}
1752+
PyErr_SetString(PyExc_TypeError, "argument must be a file object");
1753+
return NULL;
17551754

1755+
#if 0
17561756
win = getwin(PyFile_AsFile(temp));
17571757

17581758
if (win == NULL) {
@@ -1761,6 +1761,7 @@ PyCurses_GetWin(PyCursesWindowObject *self, PyObject *temp)
17611761
}
17621762

17631763
return PyCursesWindow_New(win);
1764+
#endif
17641765
}
17651766

17661767
static PyObject *

Modules/bz2module.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,6 +1075,7 @@ BZ2File_seek(BZ2FileObject *self, PyObject *args)
10751075
offset -= self->pos;
10761076
} else {
10771077
/* we cannot move back, so rewind the stream */
1078+
FILE *fp = NULL; /* XXX temporary!!! */
10781079
BZ2_bzReadClose(&bzerror, self->fp);
10791080
if (bzerror != BZ_OK) {
10801081
Util_CatchBZ2Error(bzerror);
@@ -1086,7 +1087,7 @@ BZ2File_seek(BZ2FileObject *self, PyObject *args)
10861087
Py_DECREF(ret);
10871088
ret = NULL;
10881089
self->pos = 0;
1089-
self->fp = BZ2_bzReadOpen(&bzerror, PyFile_AsFile(self->file),
1090+
self->fp = BZ2_bzReadOpen(&bzerror, fp,
10901091
0, 0, NULL, 0);
10911092
if (bzerror != BZ_OK) {
10921093
Util_CatchBZ2Error(bzerror);
@@ -1286,6 +1287,7 @@ BZ2File_init(BZ2FileObject *self, PyObject *args, PyObject *kwargs)
12861287
{
12871288
static char *kwlist[] = {"filename", "mode", "buffering",
12881289
"compresslevel", 0};
1290+
FILE *fp = NULL; /* XXX temporary!!! */
12891291
PyObject *name;
12901292
char *mode = "r";
12911293
int buffering = -1;
@@ -1347,8 +1349,8 @@ BZ2File_init(BZ2FileObject *self, PyObject *args, PyObject *kwargs)
13471349

13481350
mode = (mode_char == 'r') ? "rb" : "wb";
13491351

1350-
self->file = PyObject_CallFunction((PyObject*)&PyFile_Type, "(Osi)",
1351-
name, mode, buffering);
1352+
self->file = NULL; /* XXX io.open(name, mode, buffering); */
1353+
PyErr_SetString(PyExc_RuntimeError, "can't open bz2 files yet");
13521354
if (self->file == NULL)
13531355
return -1;
13541356

@@ -1365,11 +1367,11 @@ BZ2File_init(BZ2FileObject *self, PyObject *args, PyObject *kwargs)
13651367

13661368
if (mode_char == 'r')
13671369
self->fp = BZ2_bzReadOpen(&bzerror,
1368-
PyFile_AsFile(self->file),
1370+
fp,
13691371
0, 0, NULL, 0);
13701372
else
13711373
self->fp = BZ2_bzWriteOpen(&bzerror,
1372-
PyFile_AsFile(self->file),
1374+
fp,
13731375
compresslevel, 0, 0);
13741376

13751377
if (bzerror != BZ_OK) {

Modules/cPickle.c

Lines changed: 2 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -417,31 +417,6 @@ cPickle_ErrFormat(PyObject *ErrType, char *stringformat, char *format, ...)
417417
return NULL;
418418
}
419419

420-
static int
421-
write_file(Picklerobject *self, const char *s, Py_ssize_t n)
422-
{
423-
size_t nbyteswritten;
424-
425-
if (s == NULL) {
426-
return 0;
427-
}
428-
429-
if (n > INT_MAX) {
430-
/* String too large */
431-
return -1;
432-
}
433-
434-
Py_BEGIN_ALLOW_THREADS
435-
nbyteswritten = fwrite(s, sizeof(char), n, self->fp);
436-
Py_END_ALLOW_THREADS
437-
if (nbyteswritten != (size_t)n) {
438-
PyErr_SetFromErrno(PyExc_IOError);
439-
return -1;
440-
}
441-
442-
return (int)n;
443-
}
444-
445420
static int
446421
write_cStringIO(Picklerobject *self, const char *s, Py_ssize_t n)
447422
{
@@ -516,92 +491,6 @@ write_other(Picklerobject *self, const char *s, Py_ssize_t _n)
516491
}
517492

518493

519-
static Py_ssize_t
520-
read_file(Unpicklerobject *self, char **s, Py_ssize_t n)
521-
{
522-
size_t nbytesread;
523-
524-
if (self->buf_size == 0) {
525-
int size;
526-
527-
size = ((n < 32) ? 32 : n);
528-
if (!( self->buf = (char *)malloc(size))) {
529-
PyErr_NoMemory();
530-
return -1;
531-
}
532-
533-
self->buf_size = size;
534-
}
535-
else if (n > self->buf_size) {
536-
char *newbuf = (char *)realloc(self->buf, n);
537-
if (!newbuf) {
538-
PyErr_NoMemory();
539-
return -1;
540-
}
541-
self->buf = newbuf;
542-
self->buf_size = n;
543-
}
544-
545-
Py_BEGIN_ALLOW_THREADS
546-
nbytesread = fread(self->buf, sizeof(char), n, self->fp);
547-
Py_END_ALLOW_THREADS
548-
if (nbytesread != (size_t)n) {
549-
if (feof(self->fp)) {
550-
PyErr_SetNone(PyExc_EOFError);
551-
return -1;
552-
}
553-
554-
PyErr_SetFromErrno(PyExc_IOError);
555-
return -1;
556-
}
557-
558-
*s = self->buf;
559-
560-
return n;
561-
}
562-
563-
564-
static Py_ssize_t
565-
readline_file(Unpicklerobject *self, char **s)
566-
{
567-
int i;
568-
569-
if (self->buf_size == 0) {
570-
if (!( self->buf = (char *)malloc(40))) {
571-
PyErr_NoMemory();
572-
return -1;
573-
}
574-
self->buf_size = 40;
575-
}
576-
577-
i = 0;
578-
while (1) {
579-
int bigger;
580-
char *newbuf;
581-
for (; i < (self->buf_size - 1); i++) {
582-
if (feof(self->fp) ||
583-
(self->buf[i] = getc(self->fp)) == '\n') {
584-
self->buf[i + 1] = '\0';
585-
*s = self->buf;
586-
return i + 1;
587-
}
588-
}
589-
bigger = self->buf_size << 1;
590-
if (bigger <= 0) { /* overflow */
591-
PyErr_NoMemory();
592-
return -1;
593-
}
594-
newbuf = (char *)realloc(self->buf, bigger);
595-
if (!newbuf) {
596-
PyErr_NoMemory();
597-
return -1;
598-
}
599-
self->buf = newbuf;
600-
self->buf_size = bigger;
601-
}
602-
}
603-
604-
605494
static Py_ssize_t
606495
read_cStringIO(Unpicklerobject *self, char **s, Py_ssize_t n)
607496
{
@@ -2665,16 +2554,7 @@ newPicklerobject(PyObject *file, int proto)
26652554
if (!( self->memo = PyDict_New()))
26662555
goto err;
26672556

2668-
if (PyFile_Check(file)) {
2669-
self->fp = PyFile_AsFile(file);
2670-
if (self->fp == NULL) {
2671-
PyErr_SetString(PyExc_ValueError,
2672-
"I/O operation on closed file");
2673-
goto err;
2674-
}
2675-
self->write_func = write_file;
2676-
}
2677-
else if (PycStringIO_OutputCheck(file)) {
2557+
if (PycStringIO_OutputCheck(file)) {
26782558
self->write_func = write_cStringIO;
26792559
}
26802560
else if (file == Py_None) {
@@ -4988,17 +4868,7 @@ newUnpicklerobject(PyObject *f)
49884868
self->file = f;
49894869

49904870
/* Set read, readline based on type of f */
4991-
if (PyFile_Check(f)) {
4992-
self->fp = PyFile_AsFile(f);
4993-
if (self->fp == NULL) {
4994-
PyErr_SetString(PyExc_ValueError,
4995-
"I/O operation on closed file");
4996-
goto err;
4997-
}
4998-
self->read_func = read_file;
4999-
self->readline_func = readline_file;
5000-
}
5001-
else if (PycStringIO_InputCheck(f)) {
4871+
if (PycStringIO_InputCheck(f)) {
50024872
self->fp = NULL;
50034873
self->read_func = read_cStringIO;
50044874
self->readline_func = readline_cStringIO;

Modules/pyexpat.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -956,10 +956,7 @@ xmlparse_ParseFile(xmlparseobject *self, PyObject *f)
956956
FILE *fp;
957957
PyObject *readmethod = NULL;
958958

959-
if (PyFile_Check(f)) {
960-
fp = PyFile_AsFile(f);
961-
}
962-
else {
959+
{
963960
fp = NULL;
964961
readmethod = PyObject_GetAttrString(f, "read");
965962
if (readmethod == NULL) {

0 commit comments

Comments
 (0)
X Tutup