summaryrefslogtreecommitdiff
path: root/Python/marshal.c
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2011-11-28 19:09:45 +0100
committerAntoine Pitrou <solipsis@pitrou.net>2011-11-28 19:09:45 +0100
commit3a852cd214d726eb2bb96f94e498eda7ba042887 (patch)
tree71081d83765f4c721093b504ca9bd3b7673d41cd /Python/marshal.c
parent07ee349b41ca8f94aadaf39be3ec9ca5aca692f9 (diff)
parent07b3714e5b40f0208a7640d315213a479d3742a0 (diff)
downloadcpython-3a852cd214d726eb2bb96f94e498eda7ba042887.tar.gz
Issue #7111: Python can now be run without a stdin, stdout or stderr stream.
It was already the case with Python 2. However, the corresponding sys module entries are now set to None (instead of an unusable file object).
Diffstat (limited to 'Python/marshal.c')
-rw-r--r--Python/marshal.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/Python/marshal.c b/Python/marshal.c
index 094f732382..98bbbaff6b 100644
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -59,9 +59,9 @@ typedef struct {
/* If fp == NULL, the following are valid: */
PyObject *readable; /* Stream-like object being read from */
PyObject *str;
+ PyObject *current_filename;
char *ptr;
char *end;
- PyObject *strings; /* dict on marshal, list on unmarshal */
int version;
} WFILE;
@@ -311,9 +311,7 @@ w_object(PyObject *v, WFILE *p)
}
else if (PyUnicode_CheckExact(v)) {
PyObject *utf8;
- utf8 = PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(v),
- PyUnicode_GET_SIZE(v),
- "surrogatepass");
+ utf8 = PyUnicode_AsEncodedString(v, "utf8", "surrogatepass");
if (utf8 == NULL) {
p->depth--;
p->error = WFERR_UNMARSHALLABLE;
@@ -445,7 +443,6 @@ PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
wf.fp = fp;
wf.error = WFERR_OK;
wf.depth = 0;
- wf.strings = NULL;
wf.version = version;
w_long(x, &wf);
}
@@ -457,10 +454,8 @@ PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
wf.fp = fp;
wf.error = WFERR_OK;
wf.depth = 0;
- wf.strings = (version > 0) ? PyDict_New() : NULL;
wf.version = version;
w_object(x, &wf);
- Py_XDECREF(wf.strings);
}
typedef WFILE RFILE; /* Same struct with different invariants */
@@ -485,7 +480,9 @@ r_string(char *s, int n, RFILE *p)
}
}
else {
- PyObject *data = PyObject_CallMethod(p->readable, "read", "i", n);
+ _Py_IDENTIFIER(read);
+
+ PyObject *data = _PyObject_CallMethodId(p->readable, &PyId_read, "i", n);
read = 0;
if (data != NULL) {
if (!PyBytes_Check(data)) {
@@ -1069,6 +1066,18 @@ r_object(RFILE *p)
filename = r_object(p);
if (filename == NULL)
goto code_error;
+ if (PyUnicode_CheckExact(filename)) {
+ if (p->current_filename != NULL) {
+ if (!PyUnicode_Compare(filename, p->current_filename)) {
+ Py_DECREF(filename);
+ Py_INCREF(p->current_filename);
+ filename = p->current_filename;
+ }
+ }
+ else {
+ p->current_filename = filename;
+ }
+ }
name = r_object(p);
if (name == NULL)
goto code_error;
@@ -1131,7 +1140,7 @@ PyMarshal_ReadShortFromFile(FILE *fp)
assert(fp);
rf.readable = NULL;
rf.fp = fp;
- rf.strings = NULL;
+ rf.current_filename = NULL;
rf.end = rf.ptr = NULL;
return r_short(&rf);
}
@@ -1142,7 +1151,7 @@ PyMarshal_ReadLongFromFile(FILE *fp)
RFILE rf;
rf.fp = fp;
rf.readable = NULL;
- rf.strings = NULL;
+ rf.current_filename = NULL;
rf.ptr = rf.end = NULL;
return r_long(&rf);
}
@@ -1204,11 +1213,10 @@ PyMarshal_ReadObjectFromFile(FILE *fp)
PyObject *result;
rf.fp = fp;
rf.readable = NULL;
- rf.strings = PyList_New(0);
+ rf.current_filename = NULL;
rf.depth = 0;
rf.ptr = rf.end = NULL;
result = r_object(&rf);
- Py_DECREF(rf.strings);
return result;
}
@@ -1219,12 +1227,11 @@ PyMarshal_ReadObjectFromString(char *str, Py_ssize_t len)
PyObject *result;
rf.fp = NULL;
rf.readable = NULL;
+ rf.current_filename = NULL;
rf.ptr = str;
rf.end = str + len;
- rf.strings = PyList_New(0);
rf.depth = 0;
result = r_object(&rf);
- Py_DECREF(rf.strings);
return result;
}
@@ -1244,9 +1251,7 @@ PyMarshal_WriteObjectToString(PyObject *x, int version)
wf.error = WFERR_OK;
wf.depth = 0;
wf.version = version;
- wf.strings = (version > 0) ? PyDict_New() : NULL;
w_object(x, &wf);
- Py_XDECREF(wf.strings);
if (wf.str != NULL) {
char *base = PyBytes_AS_STRING((PyBytesObject *)wf.str);
if (wf.ptr - base > PY_SSIZE_T_MAX) {
@@ -1287,12 +1292,14 @@ marshal_dump(PyObject *self, PyObject *args)
int version = Py_MARSHAL_VERSION;
PyObject *s;
PyObject *res;
+ _Py_IDENTIFIER(write);
+
if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version))
return NULL;
s = PyMarshal_WriteObjectToString(x, version);
if (s == NULL)
return NULL;
- res = PyObject_CallMethod(f, "write", "O", s);
+ res = _PyObject_CallMethodId(f, &PyId_write, "O", s);
Py_DECREF(s);
return res;
}
@@ -1314,6 +1321,7 @@ static PyObject *
marshal_load(PyObject *self, PyObject *f)
{
PyObject *data, *result;
+ _Py_IDENTIFIER(read);
RFILE rf;
/*
@@ -1321,7 +1329,7 @@ marshal_load(PyObject *self, PyObject *f)
* This is to ensure that the object passed in at least
* has a read method which returns bytes.
*/
- data = PyObject_CallMethod(f, "read", "i", 0);
+ data = _PyObject_CallMethodId(f, &PyId_read, "i", 0);
if (data == NULL)
return NULL;
if (!PyBytes_Check(data)) {
@@ -1331,12 +1339,11 @@ marshal_load(PyObject *self, PyObject *f)
result = NULL;
}
else {
- rf.strings = PyList_New(0);
rf.depth = 0;
rf.fp = NULL;
rf.readable = f;
+ rf.current_filename = NULL;
result = read_object(&rf);
- Py_DECREF(rf.strings);
}
Py_DECREF(data);
return result;
@@ -1389,12 +1396,11 @@ marshal_loads(PyObject *self, PyObject *args)
n = p.len;
rf.fp = NULL;
rf.readable = NULL;
+ rf.current_filename = NULL;
rf.ptr = s;
rf.end = s + n;
- rf.strings = PyList_New(0);
rf.depth = 0;
result = read_object(&rf);
- Py_DECREF(rf.strings);
PyBuffer_Release(&p);
return result;
}