mirror of
https://github.com/python/cpython.git
synced 2025-07-24 19:54:21 +00:00
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.
This commit is contained in:
parent
2d5c219fe0
commit
da5b8f2d28
14 changed files with 106 additions and 2537 deletions
|
@ -659,8 +659,7 @@ builtin_exec(PyObject *self, PyObject *args)
|
|||
locals = globals;
|
||||
if (!PyString_Check(prog) &&
|
||||
!PyUnicode_Check(prog) &&
|
||||
!PyCode_Check(prog) &&
|
||||
!PyFile_Check(prog)) {
|
||||
!PyCode_Check(prog)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"exec() arg 1 must be a string, file, or code "
|
||||
"object, not %.100s", prog->ob_type->tp_name);
|
||||
|
@ -692,18 +691,6 @@ builtin_exec(PyObject *self, PyObject *args)
|
|||
}
|
||||
v = PyEval_EvalCode((PyCodeObject *) prog, globals, locals);
|
||||
}
|
||||
else if (PyFile_Check(prog)) {
|
||||
FILE *fp = PyFile_AsFile(prog);
|
||||
char *name = PyString_AsString(PyFile_Name(prog));
|
||||
PyCompilerFlags cf;
|
||||
cf.cf_flags = 0;
|
||||
if (PyEval_MergeCompilerFlags(&cf))
|
||||
v = PyRun_FileFlags(fp, name, Py_file_input, globals,
|
||||
locals, &cf);
|
||||
else
|
||||
v = PyRun_File(fp, name, Py_file_input, globals,
|
||||
locals);
|
||||
}
|
||||
else {
|
||||
char *str = source_as_string(prog);
|
||||
PyCompilerFlags cf;
|
||||
|
|
|
@ -2764,19 +2764,21 @@ static FILE *
|
|||
get_file(char *pathname, PyObject *fob, char *mode)
|
||||
{
|
||||
FILE *fp;
|
||||
if (mode[0] == 'U')
|
||||
mode = "r" PY_STDIOTEXTMODE;
|
||||
if (fob == NULL) {
|
||||
if (mode[0] == 'U')
|
||||
mode = "r" PY_STDIOTEXTMODE;
|
||||
fp = fopen(pathname, mode);
|
||||
if (fp == NULL)
|
||||
PyErr_SetFromErrno(PyExc_IOError);
|
||||
}
|
||||
else {
|
||||
fp = PyFile_AsFile(fob);
|
||||
if (fp == NULL)
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"bad/closed file object");
|
||||
int fd = PyObject_AsFileDescriptor(fob);
|
||||
if (fd == -1)
|
||||
return NULL;
|
||||
/* XXX This will leak a FILE struct. Fix this!!!!
|
||||
(But it doesn't leak a file descrioptor!) */
|
||||
fp = fdopen(fd, mode);
|
||||
}
|
||||
if (fp == NULL)
|
||||
PyErr_SetFromErrno(PyExc_IOError);
|
||||
return fp;
|
||||
}
|
||||
|
||||
|
@ -2788,8 +2790,8 @@ imp_load_compiled(PyObject *self, PyObject *args)
|
|||
PyObject *fob = NULL;
|
||||
PyObject *m;
|
||||
FILE *fp;
|
||||
if (!PyArg_ParseTuple(args, "ss|O!:load_compiled", &name, &pathname,
|
||||
&PyFile_Type, &fob))
|
||||
if (!PyArg_ParseTuple(args, "ss|O:load_compiled",
|
||||
&name, &pathname, &fob))
|
||||
return NULL;
|
||||
fp = get_file(pathname, fob, "rb");
|
||||
if (fp == NULL)
|
||||
|
@ -2810,8 +2812,8 @@ imp_load_dynamic(PyObject *self, PyObject *args)
|
|||
PyObject *fob = NULL;
|
||||
PyObject *m;
|
||||
FILE *fp = NULL;
|
||||
if (!PyArg_ParseTuple(args, "ss|O!:load_dynamic", &name, &pathname,
|
||||
&PyFile_Type, &fob))
|
||||
if (!PyArg_ParseTuple(args, "ss|O:load_dynamic",
|
||||
&name, &pathname, &fob))
|
||||
return NULL;
|
||||
if (fob) {
|
||||
fp = get_file(pathname, fob, "r");
|
||||
|
@ -2832,8 +2834,8 @@ imp_load_source(PyObject *self, PyObject *args)
|
|||
PyObject *fob = NULL;
|
||||
PyObject *m;
|
||||
FILE *fp;
|
||||
if (!PyArg_ParseTuple(args, "ss|O!:load_source", &name, &pathname,
|
||||
&PyFile_Type, &fob))
|
||||
if (!PyArg_ParseTuple(args, "ss|O:load_source",
|
||||
&name, &pathname, &fob))
|
||||
return NULL;
|
||||
fp = get_file(pathname, fob, "r");
|
||||
if (fp == NULL)
|
||||
|
@ -2873,12 +2875,7 @@ imp_load_module(PyObject *self, PyObject *args)
|
|||
if (fob == Py_None)
|
||||
fp = NULL;
|
||||
else {
|
||||
if (!PyFile_Check(fob)) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"load_module arg#2 should be a file or None");
|
||||
return NULL;
|
||||
}
|
||||
fp = get_file(pathname, fob, mode);
|
||||
fp = get_file(NULL, fob, mode);
|
||||
if (fp == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1138,81 +1138,52 @@ PyMarshal_WriteObjectToString(PyObject *x, int version)
|
|||
static PyObject *
|
||||
marshal_dump(PyObject *self, PyObject *args)
|
||||
{
|
||||
WFILE wf;
|
||||
/* XXX Quick hack -- need to do this differently */
|
||||
PyObject *x;
|
||||
PyObject *f;
|
||||
int version = Py_MARSHAL_VERSION;
|
||||
PyObject *s;
|
||||
PyObject *res;
|
||||
if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version))
|
||||
return NULL;
|
||||
if (!PyFile_Check(f)) {
|
||||
/* XXX Quick hack -- need to do this differently */
|
||||
PyObject *s = PyMarshal_WriteObjectToString(x, version);
|
||||
PyObject *res = NULL;
|
||||
if (s != NULL) {
|
||||
res = PyObject_CallMethod(f, "write", "O", s);
|
||||
Py_DECREF(s);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
wf.fp = PyFile_AsFile(f);
|
||||
wf.str = NULL;
|
||||
wf.ptr = wf.end = NULL;
|
||||
wf.error = 0;
|
||||
wf.depth = 0;
|
||||
wf.strings = (version > 0) ? PyDict_New() : 0;
|
||||
wf.version = version;
|
||||
w_object(x, &wf);
|
||||
Py_XDECREF(wf.strings);
|
||||
if (wf.error) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
(wf.error==1)?"unmarshallable object"
|
||||
:"object too deeply nested to marshal");
|
||||
s = PyMarshal_WriteObjectToString(x, version);
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
res = PyObject_CallMethod(f, "write", "O", s);
|
||||
Py_DECREF(s);
|
||||
return res;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
marshal_load(PyObject *self, PyObject *f)
|
||||
{
|
||||
/* XXX Quick hack -- need to do this differently */
|
||||
PyObject *data, *result;
|
||||
RFILE rf;
|
||||
PyObject *result;
|
||||
if (!PyFile_Check(f)) {
|
||||
/* XXX Quick hack -- need to do this differently */
|
||||
PyObject *data, *result;
|
||||
RFILE rf;
|
||||
data = PyObject_CallMethod(f, "read", "");
|
||||
if (data == NULL)
|
||||
return NULL;
|
||||
rf.fp = NULL;
|
||||
if (PyString_Check(data)) {
|
||||
rf.ptr = PyString_AS_STRING(data);
|
||||
rf.end = rf.ptr + PyString_GET_SIZE(data);
|
||||
}
|
||||
else if (PyBytes_Check(data)) {
|
||||
rf.ptr = PyBytes_AS_STRING(data);
|
||||
rf.end = rf.ptr + PyBytes_GET_SIZE(data);
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"f.read() returned neither string "
|
||||
"nor bytes but %.100s",
|
||||
data->ob_type->tp_name);
|
||||
Py_DECREF(data);
|
||||
return NULL;
|
||||
}
|
||||
rf.strings = PyList_New(0);
|
||||
result = read_object(&rf);
|
||||
Py_DECREF(rf.strings);
|
||||
Py_DECREF(data);
|
||||
return result;
|
||||
data = PyObject_CallMethod(f, "read", "");
|
||||
if (data == NULL)
|
||||
return NULL;
|
||||
rf.fp = NULL;
|
||||
if (PyString_Check(data)) {
|
||||
rf.ptr = PyString_AS_STRING(data);
|
||||
rf.end = rf.ptr + PyString_GET_SIZE(data);
|
||||
}
|
||||
else if (PyBytes_Check(data)) {
|
||||
rf.ptr = PyBytes_AS_STRING(data);
|
||||
rf.end = rf.ptr + PyBytes_GET_SIZE(data);
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"f.read() returned neither string "
|
||||
"nor bytes but %.100s",
|
||||
data->ob_type->tp_name);
|
||||
Py_DECREF(data);
|
||||
return NULL;
|
||||
}
|
||||
rf.fp = PyFile_AsFile(f);
|
||||
rf.strings = PyList_New(0);
|
||||
rf.depth = 0;
|
||||
result = read_object(&rf);
|
||||
Py_DECREF(rf.strings);
|
||||
Py_DECREF(data);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -155,7 +155,6 @@ Py_InitializeEx(int install_sigs)
|
|||
#if defined(HAVE_LANGINFO_H) && defined(CODESET)
|
||||
char *codeset;
|
||||
char *saved_locale;
|
||||
PyObject *sys_stream, *sys_isatty;
|
||||
#endif
|
||||
extern void _Py_ReadyTypes(void);
|
||||
|
||||
|
@ -273,39 +272,6 @@ Py_InitializeEx(int install_sigs)
|
|||
free(saved_locale);
|
||||
|
||||
if (codeset) {
|
||||
sys_stream = PySys_GetObject("stdin");
|
||||
sys_isatty = PyObject_CallMethod(sys_stream, "isatty", "");
|
||||
if (!sys_isatty)
|
||||
PyErr_Clear();
|
||||
if(sys_isatty && PyObject_IsTrue(sys_isatty) &&
|
||||
PyFile_Check(sys_stream)) {
|
||||
if (!PyFile_SetEncoding(sys_stream, codeset))
|
||||
Py_FatalError("Cannot set codeset of stdin");
|
||||
}
|
||||
Py_XDECREF(sys_isatty);
|
||||
|
||||
sys_stream = PySys_GetObject("stdout");
|
||||
sys_isatty = PyObject_CallMethod(sys_stream, "isatty", "");
|
||||
if (!sys_isatty)
|
||||
PyErr_Clear();
|
||||
if(sys_isatty && PyObject_IsTrue(sys_isatty) &&
|
||||
PyFile_Check(sys_stream)) {
|
||||
if (!PyFile_SetEncoding(sys_stream, codeset))
|
||||
Py_FatalError("Cannot set codeset of stdout");
|
||||
}
|
||||
Py_XDECREF(sys_isatty);
|
||||
|
||||
sys_stream = PySys_GetObject("stderr");
|
||||
sys_isatty = PyObject_CallMethod(sys_stream, "isatty", "");
|
||||
if (!sys_isatty)
|
||||
PyErr_Clear();
|
||||
if(sys_isatty && PyObject_IsTrue(sys_isatty) &&
|
||||
PyFile_Check(sys_stream)) {
|
||||
if (!PyFile_SetEncoding(sys_stream, codeset))
|
||||
Py_FatalError("Cannot set codeset of stderr");
|
||||
}
|
||||
Py_XDECREF(sys_isatty);
|
||||
|
||||
if (!Py_FileSystemDefaultEncoding)
|
||||
Py_FileSystemDefaultEncoding = codeset;
|
||||
else
|
||||
|
|
|
@ -55,18 +55,6 @@ PySys_GetObject(char *name)
|
|||
return PyDict_GetItemString(sd, name);
|
||||
}
|
||||
|
||||
FILE *
|
||||
PySys_GetFile(char *name, FILE *def)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
PyObject *v = PySys_GetObject(name);
|
||||
if (v != NULL && PyFile_Check(v))
|
||||
fp = PyFile_AsFile(v);
|
||||
if (fp == NULL)
|
||||
fp = def;
|
||||
return fp;
|
||||
}
|
||||
|
||||
int
|
||||
PySys_SetObject(char *name, PyObject *v)
|
||||
{
|
||||
|
@ -1353,25 +1341,21 @@ mywrite(char *name, FILE *fp, const char *format, va_list va)
|
|||
{
|
||||
PyObject *file;
|
||||
PyObject *error_type, *error_value, *error_traceback;
|
||||
char buffer[1001];
|
||||
int written;
|
||||
|
||||
PyErr_Fetch(&error_type, &error_value, &error_traceback);
|
||||
file = PySys_GetObject(name);
|
||||
if (file == NULL || PyFile_AsFile(file) == fp)
|
||||
vfprintf(fp, format, va);
|
||||
else {
|
||||
char buffer[1001];
|
||||
const int written = PyOS_vsnprintf(buffer, sizeof(buffer),
|
||||
format, va);
|
||||
if (PyFile_WriteString(buffer, file) != 0) {
|
||||
written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
|
||||
if (PyFile_WriteString(buffer, file) != 0) {
|
||||
PyErr_Clear();
|
||||
fputs(buffer, fp);
|
||||
}
|
||||
if (written < 0 || (size_t)written >= sizeof(buffer)) {
|
||||
const char *truncated = "... truncated";
|
||||
if (PyFile_WriteString(truncated, file) != 0) {
|
||||
PyErr_Clear();
|
||||
fputs(buffer, fp);
|
||||
}
|
||||
if (written < 0 || (size_t)written >= sizeof(buffer)) {
|
||||
const char *truncated = "... truncated";
|
||||
if (PyFile_WriteString(truncated, file) != 0) {
|
||||
PyErr_Clear();
|
||||
fputs(truncated, fp);
|
||||
}
|
||||
fputs(truncated, fp);
|
||||
}
|
||||
}
|
||||
PyErr_Restore(error_type, error_value, error_traceback);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue