Commit e4767851 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Fix some issues with file.write

It uses the buffer protocol, so make str support that better.
parent 5ba655be
......@@ -533,10 +533,9 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
/* new buffer API */
#define PyObject_CheckBuffer(obj) \
(((obj)->ob_type->tp_as_buffer != NULL) && \
(PyType_HasFeature((obj)->ob_type, Py_TPFLAGS_HAVE_NEWBUFFER)) && \
((obj)->ob_type->tp_as_buffer->bf_getbuffer != NULL))
// Pyston change: made this a function
bool _PyObject_CheckBuffer(PyObject* obj) PYSTON_NOEXCEPT;
#define PyObject_CheckBuffer(obj) _PyObject_CheckBuffer((PyObject*)(obj))
/* Return 1 if the getbuffer function is available, otherwise
return 0 */
......
......@@ -60,6 +60,11 @@ extern "C" bool _PyIndex_Check(PyObject* op) noexcept {
return PyInt_Check(op);
}
extern "C" bool _PyObject_CheckBuffer(PyObject* obj) noexcept {
return ((Py_TYPE(obj)->tp_as_buffer != NULL) && (PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_HAVE_NEWBUFFER))
&& (Py_TYPE(obj)->tp_as_buffer->bf_getbuffer != NULL));
}
extern "C" {
int Py_Py3kWarningFlag;
}
......@@ -424,8 +429,13 @@ extern "C" void PyObject_ClearWeakRefs(PyObject* object) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyObject_GetBuffer(PyObject* exporter, Py_buffer* view, int flags) noexcept {
Py_FatalError("unimplemented");
extern "C" int PyObject_GetBuffer(PyObject* obj, Py_buffer* view, int flags) noexcept {
if (!PyObject_CheckBuffer(obj)) {
printf("%s\n", obj->cls->tp_name);
PyErr_Format(PyExc_TypeError, "'%100s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
return -1;
}
return (*(obj->cls->tp_as_buffer->bf_getbuffer))(obj, view, flags);
}
extern "C" int PyObject_Print(PyObject* obj, FILE* fp, int flags) noexcept {
......@@ -1039,6 +1049,14 @@ extern "C" PyObject* PyNumber_Int(PyObject* o) noexcept {
}
extern "C" PyObject* PyNumber_Long(PyObject* o) noexcept {
// This method should do quite a bit more, including checking tp_as_number->nb_long or calling __trunc__
if (o->cls == long_cls)
return o;
if (o->cls == float_cls)
return PyLong_FromDouble(PyFloat_AsDouble(o));
Py_FatalError("unimplemented");
}
......
......@@ -22,6 +22,7 @@
#include "core/stats.h"
#include "core/types.h"
#include "gc/collector.h"
#include "runtime/capi.h"
#include "runtime/float.h"
#include "runtime/inline/boxing.h"
#include "runtime/long.h"
......@@ -36,8 +37,15 @@ extern "C" unsigned long PyInt_AsUnsignedLongMask(PyObject* op) noexcept {
}
extern "C" long PyInt_AsLong(PyObject* op) noexcept {
RELEASE_ASSERT(isSubclass(op->cls, int_cls), "");
return static_cast<BoxedInt*>(op)->n;
// This method should do quite a bit more, including checking tp_as_number->nb_int (or calling __int__?)
if (op->cls == int_cls)
return static_cast<BoxedInt*>(op)->n;
if (op->cls == long_cls)
return PyLong_AsLong(op);
Py_FatalError("unimplemented");
}
extern "C" Py_ssize_t PyInt_AsSsize_t(PyObject* op) noexcept {
......
......@@ -1881,12 +1881,17 @@ static Py_ssize_t string_buffer_getsegcount(PyObject* o, Py_ssize_t* lenp) noexc
return 1;
}
static int string_buffer_getbuffer(BoxedString* self, Py_buffer* view, int flags) noexcept {
assert(self->cls == str_cls);
return PyBuffer_FillInfo(view, (PyObject*)self, &self->s[0], self->s.size(), 1, flags);
}
static PyBufferProcs string_as_buffer = {
(readbufferproc)string_buffer_getreadbuf, // comments are the only way I've found of
(writebufferproc)NULL, // forcing clang-format to break these onto multiple lines
(segcountproc)string_buffer_getsegcount, //
(charbufferproc)NULL, //
(getbufferproc)NULL, //
(getbufferproc)string_buffer_getbuffer, //
(releasebufferproc)NULL,
};
......@@ -1899,6 +1904,7 @@ void strDestructor(Box* b) {
void setupStr() {
str_cls->simple_destructor = strDestructor;
str_cls->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
str_iterator_cls
= new BoxedHeapClass(object_cls, &strIteratorGCHandler, 0, sizeof(BoxedStringIterator), false, "striterator");
......
# allow-warning: converting unicode literal to str
import os
import tempfile
fd, fn = tempfile.mkstemp()
with open(fn, "wb") as f:
f.write("hello world!")
with open(fn) as f:
print repr(f.read())
with open(fn, "w") as f:
f.write("hello world!")
with open(fn) as f:
print repr(f.read())
with open(fn, "ab") as f:
f.write("hello world!")
with open(fn) as f:
print repr(f.read())
os.unlink(fn)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment