Commit 550e52ed authored by Marius Wachtler's avatar Marius Wachtler

switch to cpythons fileobject implementation

fixes test_file2k, test_file_eintr and test_softspace
parent 8cf264f2
...@@ -89,6 +89,7 @@ file(GLOB_RECURSE STDOBJECT_SRCS Objects ...@@ -89,6 +89,7 @@ file(GLOB_RECURSE STDOBJECT_SRCS Objects
dictproxy.c dictproxy.c
exceptions.c exceptions.c
floatobject.c floatobject.c
fileobject.c
iterobject.c iterobject.c
memoryobject.c memoryobject.c
stringobject.c stringobject.c
......
...@@ -8,8 +8,6 @@ ...@@ -8,8 +8,6 @@
extern "C" { extern "C" {
#endif #endif
// Pyston change: this is not our format
#if 0
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
FILE *f_fp; FILE *f_fp;
...@@ -34,15 +32,8 @@ typedef struct { ...@@ -34,15 +32,8 @@ typedef struct {
int readable; int readable;
int writable; int writable;
} PyFileObject; } PyFileObject;
#endif
typedef struct _PyFileObject PyFileObject;
// Pyston change: use this to access the fp instead of ->f_fp
PyAPI_FUNC(void) PyFile_SetFP(PyObject*, FILE*) PYSTON_NOEXCEPT;
// Pyston change: this is no longer a static object PyAPI_DATA(PyTypeObject) PyFile_Type;
PyAPI_DATA(PyTypeObject*) file_cls;
#define PyFile_Type (*file_cls)
#define PyFile_Check(op) PyObject_TypeCheck(op, &PyFile_Type) #define PyFile_Check(op) PyObject_TypeCheck(op, &PyFile_Type)
#define PyFile_CheckExact(op) (Py_TYPE(op) == &PyFile_Type) #define PyFile_CheckExact(op) (Py_TYPE(op) == &PyFile_Type)
...@@ -63,9 +54,6 @@ PyAPI_FUNC(int) PyFile_SoftSpace(PyObject *, int) PYSTON_NOEXCEPT; ...@@ -63,9 +54,6 @@ PyAPI_FUNC(int) PyFile_SoftSpace(PyObject *, int) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *) PYSTON_NOEXCEPT; PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *) PYSTON_NOEXCEPT; PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *) PYSTON_NOEXCEPT;
// Pyston temporary addition:
PyAPI_FUNC(PyObject *) PyFile_GetEncoding(PyObject *) PYSTON_NOEXCEPT;
/* The default encoding used by the platform file system APIs /* The default encoding used by the platform file system APIs
If non-NULL, this is different than the default encoding for strings If non-NULL, this is different than the default encoding for strings
*/ */
......
# expected: fail
import sys import sys
import os import os
import unittest import unittest
...@@ -30,6 +29,8 @@ class AutoFileTests(unittest.TestCase): ...@@ -30,6 +29,8 @@ class AutoFileTests(unittest.TestCase):
self.f.close() self.f.close()
os.remove(TESTFN) os.remove(TESTFN)
# Pyston change: disabled
@unittest.skip("this depends on refcounting")
def testWeakRefs(self): def testWeakRefs(self):
# verify weak references # verify weak references
p = proxy(self.f) p = proxy(self.f)
......
# expected: fail
# Written to test interrupted system calls interfering with our many buffered # Written to test interrupted system calls interfering with our many buffered
# IO implementations. http://bugs.python.org/issue12268 # IO implementations. http://bugs.python.org/issue12268
# #
......
# expected: fail
from test.test_support import run_unittest from test.test_support import run_unittest
import unittest import unittest
import StringIO import StringIO
......
...@@ -89,6 +89,6 @@ AttrwrapperType = type(_C().__dict__) ...@@ -89,6 +89,6 @@ AttrwrapperType = type(_C().__dict__)
GetSetDescriptorType = type(FunctionType.func_code) GetSetDescriptorType = type(FunctionType.func_code)
# Pyston change: # Pyston change:
# MemberDescriptorType = type(FunctionType.func_globals) # MemberDescriptorType = type(FunctionType.func_globals)
MemberDescriptorType = type(file.softspace) MemberDescriptorType = type(type.__dict__["__flags__"])
del sys, _f, _g, _C, _x # Not for export del sys, _f, _g, _C, _x # Not for export
...@@ -6914,11 +6914,7 @@ posix_fdopen(PyObject *self, PyObject *args) ...@@ -6914,11 +6914,7 @@ posix_fdopen(PyObject *self, PyObject *args)
if (fp == NULL) if (fp == NULL)
return posix_error(); return posix_error();
/* We now know we will succeed, so initialize the file object. */ /* We now know we will succeed, so initialize the file object. */
((PyFileObject *)f)->f_fp = fp;
// Pyston change:
PyFile_SetFP(f, fp);
//((PyFileObject *)f)->f_fp = fp;
PyFile_SetBufSize(f, bufsize); PyFile_SetBufSize(f, bufsize);
return f; return f;
} }
......
// This file is originally from CPython 2.7, with modifications for Pyston
/* File object implementation */ /* File object implementation */
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
...@@ -138,7 +140,7 @@ dircheck(PyFileObject* f) ...@@ -138,7 +140,7 @@ dircheck(PyFileObject* f)
static PyObject * static PyObject *
fill_file_fields(PyFileObject *f, FILE *fp, PyObject *name, char *mode, fill_file_fields(PyFileObject *f, FILE *fp, PyObject *name, const char *mode,
int (*close)(FILE *)) int (*close)(FILE *))
{ {
assert(name != NULL); assert(name != NULL);
...@@ -427,7 +429,9 @@ close_the_file(PyFileObject *f) ...@@ -427,7 +429,9 @@ close_the_file(PyFileObject *f)
if (local_fp != NULL) { if (local_fp != NULL) {
local_close = f->f_close; local_close = f->f_close;
if (local_close != NULL && f->unlocked_count > 0) { if (local_close != NULL && f->unlocked_count > 0) {
if (f->ob_refcnt > 0) { // Pyston change:
// if (f->ob_refcnt > 0) {
if (/*f->ob_refcnt*/ 2 > 0) {
PyErr_SetString(PyExc_IOError, PyErr_SetString(PyExc_IOError,
"close() called during concurrent " "close() called during concurrent "
"operation on the same file object."); "operation on the same file object.");
...@@ -466,7 +470,7 @@ close_the_file(PyFileObject *f) ...@@ -466,7 +470,7 @@ close_the_file(PyFileObject *f)
} }
PyObject * PyObject *
PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *)) PyFile_FromFile(FILE *fp, const char *name, const char *mode, int (*close)(FILE *))
{ {
PyFileObject *f; PyFileObject *f;
PyObject *o_name; PyObject *o_name;
...@@ -1596,7 +1600,9 @@ PyFile_GetLine(PyObject *f, int n) ...@@ -1596,7 +1600,9 @@ PyFile_GetLine(PyObject *f, int n)
"EOF when reading a line"); "EOF when reading a line");
} }
else if (s[len-1] == '\n') { else if (s[len-1] == '\n') {
if (result->ob_refcnt == 1) { // Pyston change:
// if (result->ob_refcnt == 1) {
if (/*result->ob_refcnt*/ 2 == 1) {
if (_PyString_Resize(&result, len-1)) if (_PyString_Resize(&result, len-1))
return NULL; return NULL;
} }
...@@ -1619,7 +1625,9 @@ PyFile_GetLine(PyObject *f, int n) ...@@ -1619,7 +1625,9 @@ PyFile_GetLine(PyObject *f, int n)
"EOF when reading a line"); "EOF when reading a line");
} }
else if (s[len-1] == '\n') { else if (s[len-1] == '\n') {
if (result->ob_refcnt == 1) // Pyston change:
// if (result->ob_refcnt == 1)
if (/*result->ob_refcnt*/ 2 == 1)
PyUnicode_Resize(&result, len-1); PyUnicode_Resize(&result, len-1);
else { else {
PyObject *v; PyObject *v;
...@@ -2466,7 +2474,9 @@ PyDoc_STR( ...@@ -2466,7 +2474,9 @@ PyDoc_STR(
); );
PyTypeObject PyFile_Type = { PyTypeObject PyFile_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0) // Pyston change:
// PyVarObject_HEAD_INIT(&PyType_Type, 0)
PyVarObject_HEAD_INIT(NULL, 0)
"file", "file",
sizeof(PyFileObject), sizeof(PyFileObject),
0, 0,
......
...@@ -783,7 +783,7 @@ tok_stdin_decode(struct tok_state *tok, char **inp) ...@@ -783,7 +783,7 @@ tok_stdin_decode(struct tok_state *tok, char **inp)
if (sysstdin == NULL || !PyFile_Check(sysstdin)) if (sysstdin == NULL || !PyFile_Check(sysstdin))
return 0; return 0;
enc = PyFile_GetEncoding(sysstdin); enc = ((PyFileObject*)sysstdin)->f_encoding;
if (enc == NULL || !PyString_Check(enc)) if (enc == NULL || !PyString_Check(enc))
return 0; return 0;
Py_INCREF(enc); Py_INCREF(enc);
......
...@@ -91,7 +91,6 @@ add_library(PYSTON_OBJECTS OBJECT ${OPTIONAL_SRCS} ...@@ -91,7 +91,6 @@ add_library(PYSTON_OBJECTS OBJECT ${OPTIONAL_SRCS}
runtime/descr.cpp runtime/descr.cpp
runtime/dict.cpp runtime/dict.cpp
runtime/exceptions.cpp runtime/exceptions.cpp
runtime/file.cpp
runtime/float.cpp runtime/float.cpp
runtime/frame.cpp runtime/frame.cpp
runtime/generator.cpp runtime/generator.cpp
......
...@@ -179,8 +179,6 @@ void initGlobalFuncs(GlobalState& g) { ...@@ -179,8 +179,6 @@ void initGlobalFuncs(GlobalState& g) {
g.funcs.allowGLReadPreemption = getFunc((void*)threading::allowGLReadPreemption, "allowGLReadPreemption"); g.funcs.allowGLReadPreemption = getFunc((void*)threading::allowGLReadPreemption, "allowGLReadPreemption");
GET(softspace);
GET(createFunctionFromMetadata); GET(createFunctionFromMetadata);
GET(getFunctionMetadata); GET(getFunctionMetadata);
GET(createUserClass); GET(createUserClass);
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include "core/ast.h" #include "core/ast.h"
#include "core/types.h" #include "core/types.h"
#include "runtime/classobj.h" #include "runtime/classobj.h"
#include "runtime/file.h"
#include "runtime/ics.h" #include "runtime/ics.h"
#include "runtime/import.h" #include "runtime/import.h"
#include "runtime/inline/list.h" #include "runtime/inline/list.h"
...@@ -309,7 +308,7 @@ Box* open(Box* arg1, Box* arg2, Box* arg3) { ...@@ -309,7 +308,7 @@ Box* open(Box* arg1, Box* arg2, Box* arg3) {
assert(arg2); assert(arg2);
assert(arg3); assert(arg3);
// This could be optimized quite a bit if it ends up being important: // This could be optimized quite a bit if it ends up being important:
return runtimeCall(file_cls, ArgPassSpec(3), arg1, arg2, arg3, NULL, NULL); return runtimeCall(&PyFile_Type, ArgPassSpec(3), arg1, arg2, arg3, NULL, NULL);
} }
extern "C" Box* chr(Box* arg) { extern "C" Box* chr(Box* arg) {
...@@ -2015,7 +2014,7 @@ void setupBuiltins() { ...@@ -2015,7 +2014,7 @@ void setupBuiltins() {
builtins_module->giveAttr("xrange", xrange_cls); builtins_module->giveAttr("xrange", xrange_cls);
open_obj = new BoxedBuiltinFunctionOrMethod( open_obj = new BoxedBuiltinFunctionOrMethod(
FunctionMetadata::create((void*)open, typeFromClass(file_cls), 3, false, false, FunctionMetadata::create((void*)open, typeFromClass(&PyFile_Type), 3, false, false,
ParamNames({ "name", "mode", "buffering" }, "", "")), ParamNames({ "name", "mode", "buffering" }, "", "")),
"open", { boxString("r"), boxInt(-1) }, NULL, open_doc); "open", { boxString("r"), boxInt(-1) }, NULL, open_doc);
builtins_module->giveAttr("open", open_obj); builtins_module->giveAttr("open", open_obj);
...@@ -2078,7 +2077,7 @@ void setupBuiltins() { ...@@ -2078,7 +2077,7 @@ void setupBuiltins() {
builtins_module->giveAttr("list", list_cls); builtins_module->giveAttr("list", list_cls);
builtins_module->giveAttr("slice", slice_cls); builtins_module->giveAttr("slice", slice_cls);
builtins_module->giveAttr("type", type_cls); builtins_module->giveAttr("type", type_cls);
builtins_module->giveAttr("file", file_cls); builtins_module->giveAttr("file", &PyFile_Type);
builtins_module->giveAttr("bool", bool_cls); builtins_module->giveAttr("bool", bool_cls);
builtins_module->giveAttr("dict", dict_cls); builtins_module->giveAttr("dict", dict_cls);
builtins_module->giveAttr("set", set_cls); builtins_module->giveAttr("set", set_cls);
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include "capi/types.h" #include "capi/types.h"
#include "codegen/unwinding.h" #include "codegen/unwinding.h"
#include "core/types.h" #include "core/types.h"
#include "runtime/file.h"
#include "runtime/inline/boxing.h" #include "runtime/inline/boxing.h"
#include "runtime/inline/list.h" #include "runtime/inline/list.h"
#include "runtime/int.h" #include "runtime/int.h"
...@@ -101,7 +100,8 @@ BoxedList* getSysPath() { ...@@ -101,7 +100,8 @@ BoxedList* getSysPath() {
Box* getSysStdout() { Box* getSysStdout() {
Box* sys_stdout = sys_module->getattr(internStringMortal("stdout")); Box* sys_stdout = sys_module->getattr(internStringMortal("stdout"));
RELEASE_ASSERT(sys_stdout, "lost sys.stdout??"); if (!sys_stdout)
raiseExcHelper(RuntimeError, "lost sys.stdout");
return sys_stdout; return sys_stdout;
} }
...@@ -653,13 +653,6 @@ void setupSys() { ...@@ -653,13 +653,6 @@ void setupSys() {
sys_module->giveAttr("argv", new BoxedList()); sys_module->giveAttr("argv", new BoxedList());
sys_module->giveAttr("stdout", new BoxedFile(stdout, "<stdout>", "w"));
sys_module->giveAttr("stdin", new BoxedFile(stdin, "<stdin>", "r"));
sys_module->giveAttr("stderr", new BoxedFile(stderr, "<stderr>", "w"));
sys_module->giveAttr("__stdout__", sys_module->getattr(internStringMortal("stdout")));
sys_module->giveAttr("__stdin__", sys_module->getattr(internStringMortal("stdin")));
sys_module->giveAttr("__stderr__", sys_module->getattr(internStringMortal("stderr")));
sys_module->giveAttr("exc_info", sys_module->giveAttr("exc_info",
new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)sysExcInfo, BOXED_TUPLE, 0), new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)sysExcInfo, BOXED_TUPLE, 0),
"exc_info", exc_info_doc)); "exc_info", exc_info_doc));
......
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
#include "core/threading.h" #include "core/threading.h"
#include "core/types.h" #include "core/types.h"
#include "runtime/classobj.h" #include "runtime/classobj.h"
#include "runtime/file.h"
#include "runtime/import.h" #include "runtime/import.h"
#include "runtime/objmodel.h" #include "runtime/objmodel.h"
#include "runtime/rewrite_args.h" #include "runtime/rewrite_args.h"
...@@ -933,7 +932,7 @@ extern "C" PyObject* PyExceptionInstance_Class(PyObject* o) noexcept { ...@@ -933,7 +932,7 @@ extern "C" PyObject* PyExceptionInstance_Class(PyObject* o) noexcept {
} }
extern "C" int PyTraceBack_Print(PyObject* v, PyObject* f) noexcept { extern "C" int PyTraceBack_Print(PyObject* v, PyObject* f) noexcept {
RELEASE_ASSERT(f->cls == file_cls && static_cast<BoxedFile*>(f)->f_fp == stderr, RELEASE_ASSERT(f->cls == &PyFile_Type && ((PyFileObject*)f)->f_fp == stderr,
"sorry will only print tracebacks to stderr right now"); "sorry will only print tracebacks to stderr right now");
printTraceback(v); printTraceback(v);
return 0; return 0;
......
This diff is collapsed.
// Copyright (c) 2014-2015 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef PYSTON_RUNTIME_FILE_H
#define PYSTON_RUNTIME_FILE_H
#include "core/types.h"
#include "runtime/types.h"
namespace pyston {
class BoxedFile : public Box {
public:
PyObject_HEAD;
FILE* f_fp;
PyObject* f_name;
PyObject* f_mode;
int (*f_close)(FILE*);
int f_softspace; /* Flag used by 'print' command */
int f_binary; /* Flag which indicates whether the file is
open in binary (1) or text (0) mode */
char* f_buf; /* Allocated readahead buffer */
char* f_bufend; /* Points after last occupied position */
char* f_bufptr; /* Current buffer position */
char* f_setbuf; /* Buffer for setbuf(3) and setvbuf(3) */
int f_univ_newline; /* Handle any newline convention */
int f_newlinetypes; /* Types of newlines seen */
int f_skipnextlf; /* Skip next \n */
PyObject* f_encoding;
PyObject* f_errors;
PyObject* weakreflist; /* List of weak references */
int unlocked_count; /* Num. currently running sections of code
using f_fp with the GIL released. */
int readable;
int writable;
BoxedFile(FILE* f, std::string fname, const char* fmode, int (*close)(FILE*) = fclose)
__attribute__((visibility("default")));
DEFAULT_CLASS(file_cls);
static void gcHandler(GCVisitor* v, Box* b);
};
}
#endif
...@@ -735,7 +735,7 @@ Box* impFindModule(Box* _name, BoxedList* path) { ...@@ -735,7 +735,7 @@ Box* impFindModule(Box* _name, BoxedList* path) {
if (sr.type == SearchResult::PY_SOURCE) { if (sr.type == SearchResult::PY_SOURCE) {
Box* path = boxString(sr.path); Box* path = boxString(sr.path);
Box* mode = boxString("r"); Box* mode = boxString("r");
Box* f = runtimeCall(file_cls, ArgPassSpec(2), path, mode, NULL, NULL, NULL); Box* f = runtimeCall(&PyFile_Type, ArgPassSpec(2), path, mode, NULL, NULL, NULL);
return BoxedTuple::create({ f, path, BoxedTuple::create({ boxString(".py"), mode, boxInt(sr.type) }) }); return BoxedTuple::create({ f, path, BoxedTuple::create({ boxString(".py"), mode, boxInt(sr.type) }) });
} }
...@@ -748,7 +748,7 @@ Box* impFindModule(Box* _name, BoxedList* path) { ...@@ -748,7 +748,7 @@ Box* impFindModule(Box* _name, BoxedList* path) {
if (sr.type == SearchResult::C_EXTENSION) { if (sr.type == SearchResult::C_EXTENSION) {
Box* path = boxString(sr.path); Box* path = boxString(sr.path);
Box* mode = boxString("rb"); Box* mode = boxString("rb");
Box* f = runtimeCall(file_cls, ArgPassSpec(2), path, mode, NULL, NULL, NULL); Box* f = runtimeCall(&PyFile_Type, ArgPassSpec(2), path, mode, NULL, NULL, NULL);
return BoxedTuple::create({ f, path, BoxedTuple::create({ boxString(".so"), mode, boxInt(sr.type) }) }); return BoxedTuple::create({ f, path, BoxedTuple::create({ boxString(".so"), mode, boxInt(sr.type) }) });
} }
...@@ -783,7 +783,7 @@ Box* impLoadModule(Box* _name, Box* _file, Box* _pathname, Box** args) { ...@@ -783,7 +783,7 @@ Box* impLoadModule(Box* _name, Box* _file, Box* _pathname, Box** args) {
RELEASE_ASSERT(_file == None, ""); RELEASE_ASSERT(_file == None, "");
return createAndRunModule(name, (llvm::Twine(pathname->s()) + "/__init__.py").str(), pathname->s()); return createAndRunModule(name, (llvm::Twine(pathname->s()) + "/__init__.py").str(), pathname->s());
} else if (type->n == SearchResult::PY_SOURCE) { } else if (type->n == SearchResult::PY_SOURCE) {
RELEASE_ASSERT(_file->cls == file_cls, ""); RELEASE_ASSERT(_file->cls == &PyFile_Type, "");
return createAndRunModule(name, pathname->s()); return createAndRunModule(name, pathname->s());
} }
......
...@@ -48,7 +48,6 @@ AST_stmt* _asttmt_forcer; ...@@ -48,7 +48,6 @@ AST_stmt* _asttmt_forcer;
#define FORCE(name) forceLink((void*)name) #define FORCE(name) forceLink((void*)name)
void force() { void force() {
FORCE(softspace);
FORCE(my_assert); FORCE(my_assert);
FORCE(boxInt); FORCE(boxInt);
......
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
#include "gc/gc.h" #include "gc/gc.h"
#include "runtime/classobj.h" #include "runtime/classobj.h"
#include "runtime/dict.h" #include "runtime/dict.h"
#include "runtime/file.h"
#include "runtime/float.h" #include "runtime/float.h"
#include "runtime/generator.h" #include "runtime/generator.h"
#include "runtime/hiddenclass.h" #include "runtime/hiddenclass.h"
...@@ -141,74 +140,65 @@ extern "C" Box* deopt(AST_expr* expr, Box* value) { ...@@ -141,74 +140,65 @@ extern "C" Box* deopt(AST_expr* expr, Box* value) {
return astInterpretDeopt(deopt_state.cf->md, expr, deopt_state.current_stmt, value, deopt_state.frame_state); return astInterpretDeopt(deopt_state.cf->md, expr, deopt_state.current_stmt, value, deopt_state.frame_state);
} }
extern "C" bool softspace(Box* b, bool newval) { extern "C" void printHelper(Box* w, Box* v, bool nl) {
assert(b); if (w == None)
w = getSysStdout();
// TODO do we also need to wrap the isSubclass in the try{}? it
// can throw exceptions which would bubble up from print int err = 0;
// statements.
if (isSubclass(b->cls, file_cls)) { // copied from cpythons PRINT_ITEM and PRINT_NEWLINE op handling code
int& ss = static_cast<BoxedFile*>(b)->f_softspace; if (v) {
int r = ss; /* PyFile_SoftSpace() can exececute arbitrary code
ss = newval; if sys.stdout is an instance with a __getattr__.
assert(r == 0 || r == 1); If __getattr__ raises an exception, w will
return (bool)r; be freed, so we need to prevent that temporarily. */
} Py_XINCREF(w);
if (w != NULL && PyFile_SoftSpace(w, 0))
static BoxedString* softspace_str = internStringImmortal("softspace"); err = PyFile_WriteString(" ", w);
if (err == 0)
bool r; err = PyFile_WriteObject(v, w, Py_PRINT_RAW);
Box* gotten = NULL; if (err == 0) {
try { /* XXX move into writeobject() ? */
Box* gotten = getattrInternal<CXX>(b, softspace_str); if (PyString_Check(v)) {
if (!gotten) { char* s = PyString_AS_STRING(v);
r = 0; Py_ssize_t len = PyString_GET_SIZE(v);
} else { if (len == 0 || !isspace(Py_CHARMASK(s[len - 1])) || s[len - 1] == ' ')
r = nonzero(gotten); PyFile_SoftSpace(w, 1);
}
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(v)) {
Py_UNICODE* s = PyUnicode_AS_UNICODE(v);
Py_ssize_t len = PyUnicode_GET_SIZE(v);
if (len == 0 || !Py_UNICODE_ISSPACE(s[len - 1]) || s[len - 1] == ' ')
PyFile_SoftSpace(w, 1);
}
#endif
else
PyFile_SoftSpace(w, 1);
} }
} catch (ExcInfo e) { Py_XDECREF(w);
r = 0; Py_DECREF(v);
} // Py_XDECREF(stream);
// stream = NULL;
try { if (err != 0)
setattr(b, softspace_str, boxInt(newval)); throwCAPIException();
} catch (ExcInfo e) {
r = 0;
}
return r;
}
extern "C" void printHelper(Box* dest, Box* var, bool nl) {
static BoxedString* write_str = internStringImmortal("write");
static BoxedString* newline_str = internStringImmortal("\n");
static BoxedString* space_str = internStringImmortal(" ");
if (dest == None)
dest = getSysStdout();
if (var) {
// begin code for handling of softspace
bool new_softspace = !nl;
if (softspace(dest, new_softspace))
callattrInternal<CXX, NOT_REWRITABLE>(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1), space_str, 0, 0, 0,
0);
Box* str_or_unicode_var = (var->cls == unicode_cls) ? var : str(var);
Box* write_rtn = callattrInternal<CXX, NOT_REWRITABLE>(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1),
str_or_unicode_var, 0, 0, 0, 0);
if (!write_rtn)
raiseAttributeError(dest, write_str->s());
} }
if (nl) { if (nl) {
Box* write_rtn = callattrInternal<CXX, NOT_REWRITABLE>(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1), if (w != NULL) {
newline_str, 0, 0, 0, 0); /* w.write() may replace sys.stdout, so we
if (!write_rtn) * have to keep our reference to it */
raiseAttributeError(dest, write_str->s()); Py_INCREF(w);
if (!var) err = PyFile_WriteString("\n", w);
softspace(dest, false); if (err == 0)
PyFile_SoftSpace(w, 0);
Py_DECREF(w);
}
// Py_XDECREF(stream);
} }
if (err != 0)
throwCAPIException();
} }
extern "C" void my_assert(bool b) { extern "C" void my_assert(bool b) {
...@@ -2645,7 +2635,7 @@ extern "C" bool nonzero(Box* obj) { ...@@ -2645,7 +2635,7 @@ extern "C" bool nonzero(Box* obj) {
crewrite_args.assertReturnConvention(ReturnConvention::NO_RETURN); crewrite_args.assertReturnConvention(ReturnConvention::NO_RETURN);
} }
ASSERT(obj->cls->is_user_defined || obj->cls->instances_are_nonzero || obj->cls == classobj_cls ASSERT(obj->cls->is_user_defined || obj->cls->instances_are_nonzero || obj->cls == classobj_cls
|| obj->cls == type_cls || isSubclass(obj->cls, Exception) || obj->cls == file_cls || obj->cls == type_cls || isSubclass(obj->cls, Exception) || obj->cls == &PyFile_Type
|| obj->cls == traceback_cls || obj->cls == instancemethod_cls || obj->cls == module_cls || obj->cls == traceback_cls || obj->cls == instancemethod_cls || obj->cls == module_cls
|| obj->cls == capifunc_cls || obj->cls == builtin_function_or_method_cls || obj->cls == capifunc_cls || obj->cls == builtin_function_or_method_cls
|| obj->cls == method_cls || obj->cls == frame_cls || obj->cls == generator_cls || obj->cls == method_cls || obj->cls == frame_cls || obj->cls == generator_cls
......
...@@ -48,7 +48,6 @@ __attribute__((format(printf, 2, 3))); ...@@ -48,7 +48,6 @@ __attribute__((format(printf, 2, 3)));
void raiseExcHelper(BoxedClass*, Box* arg) __attribute__((__noreturn__)); void raiseExcHelper(BoxedClass*, Box* arg) __attribute__((__noreturn__));
// TODO sort this // TODO sort this
extern "C" bool softspace(Box* b, bool newval);
extern "C" void printHelper(Box* dest, Box* var, bool nl); extern "C" void printHelper(Box* dest, Box* var, bool nl);
extern "C" void my_assert(bool b); extern "C" void my_assert(bool b);
extern "C" Box* getattr(Box* obj, BoxedString* attr); extern "C" Box* getattr(Box* obj, BoxedString* attr);
......
...@@ -37,7 +37,6 @@ ...@@ -37,7 +37,6 @@
#include "runtime/code.h" #include "runtime/code.h"
#include "runtime/complex.h" #include "runtime/complex.h"
#include "runtime/dict.h" #include "runtime/dict.h"
#include "runtime/file.h"
#include "runtime/hiddenclass.h" #include "runtime/hiddenclass.h"
#include "runtime/ics.h" #include "runtime/ics.h"
#include "runtime/iterobject.h" #include "runtime/iterobject.h"
...@@ -1568,9 +1567,9 @@ void BoxedClosure::gcHandler(GCVisitor* v, Box* b) { ...@@ -1568,9 +1567,9 @@ void BoxedClosure::gcHandler(GCVisitor* v, Box* b) {
extern "C" { extern "C" {
BoxedClass* object_cls, *type_cls, *none_cls, *bool_cls, *int_cls, *float_cls, BoxedClass* object_cls, *type_cls, *none_cls, *bool_cls, *int_cls, *float_cls,
* str_cls = NULL, *function_cls, *instancemethod_cls, *list_cls, *slice_cls, *module_cls, *dict_cls, *tuple_cls, * str_cls = NULL, *function_cls, *instancemethod_cls, *list_cls, *slice_cls, *module_cls, *dict_cls, *tuple_cls,
*file_cls, *member_descriptor_cls, *closure_cls, *generator_cls, *null_importer_cls, *complex_cls, *member_descriptor_cls, *closure_cls, *generator_cls, *null_importer_cls, *complex_cls, *basestring_cls,
*basestring_cls, *property_cls, *staticmethod_cls, *classmethod_cls, *attrwrapper_cls, *pyston_getset_cls, *property_cls, *staticmethod_cls, *classmethod_cls, *attrwrapper_cls, *pyston_getset_cls, *capi_getset_cls,
*capi_getset_cls, *builtin_function_or_method_cls, *attrwrapperiter_cls, *set_cls, *frozenset_cls; *builtin_function_or_method_cls, *attrwrapperiter_cls, *set_cls, *frozenset_cls;
BoxedTuple* EmptyTuple; BoxedTuple* EmptyTuple;
} }
...@@ -3629,6 +3628,11 @@ static Box* getsetDelete(Box* self, Box* obj) { ...@@ -3629,6 +3628,11 @@ static Box* getsetDelete(Box* self, Box* obj) {
return getsetSet(self, obj, NULL); return getsetSet(self, obj, NULL);
} }
static int _check_and_flush(FILE* stream) {
int prev_fail = ferror(stream);
return fflush(stream) || prev_fail ? EOF : 0;
}
bool TRACK_ALLOCATIONS = false; bool TRACK_ALLOCATIONS = false;
void setupRuntime() { void setupRuntime() {
...@@ -3704,8 +3708,6 @@ void setupRuntime() { ...@@ -3704,8 +3708,6 @@ void setupRuntime() {
BoxedClass(object_cls, &AttrWrapper::gcHandler, 0, 0, sizeof(AttrWrapper), false, "attrwrapper"); BoxedClass(object_cls, &AttrWrapper::gcHandler, 0, 0, sizeof(AttrWrapper), false, "attrwrapper");
dict_cls = new (0) BoxedClass(object_cls, &BoxedDict::gcHandler, 0, 0, sizeof(BoxedDict), false, "dict"); dict_cls = new (0) BoxedClass(object_cls, &BoxedDict::gcHandler, 0, 0, sizeof(BoxedDict), false, "dict");
dict_cls->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS; dict_cls->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS;
file_cls = new (0) BoxedClass(object_cls, &BoxedFile::gcHandler, 0, offsetof(BoxedFile, weakreflist),
sizeof(BoxedFile), false, "file");
int_cls = new (0) BoxedClass(object_cls, NULL, 0, 0, sizeof(BoxedInt), false, "int"); int_cls = new (0) BoxedClass(object_cls, NULL, 0, 0, sizeof(BoxedInt), false, "int");
int_cls->tp_flags |= Py_TPFLAGS_INT_SUBCLASS; int_cls->tp_flags |= Py_TPFLAGS_INT_SUBCLASS;
bool_cls = new (0) BoxedClass(int_cls, NULL, 0, 0, sizeof(BoxedBool), false, "bool", false); bool_cls = new (0) BoxedClass(int_cls, NULL, 0, 0, sizeof(BoxedBool), false, "bool", false);
...@@ -3755,7 +3757,6 @@ void setupRuntime() { ...@@ -3755,7 +3757,6 @@ void setupRuntime() {
pyston_getset_cls->tp_mro = BoxedTuple::create({ pyston_getset_cls, object_cls }); pyston_getset_cls->tp_mro = BoxedTuple::create({ pyston_getset_cls, object_cls });
attrwrapper_cls->tp_mro = BoxedTuple::create({ attrwrapper_cls, object_cls }); attrwrapper_cls->tp_mro = BoxedTuple::create({ attrwrapper_cls, object_cls });
dict_cls->tp_mro = BoxedTuple::create({ dict_cls, object_cls }); dict_cls->tp_mro = BoxedTuple::create({ dict_cls, object_cls });
file_cls->tp_mro = BoxedTuple::create({ file_cls, object_cls });
int_cls->tp_mro = BoxedTuple::create({ int_cls, object_cls }); int_cls->tp_mro = BoxedTuple::create({ int_cls, object_cls });
bool_cls->tp_mro = BoxedTuple::create({ bool_cls, object_cls }); bool_cls->tp_mro = BoxedTuple::create({ bool_cls, object_cls });
complex_cls->tp_mro = BoxedTuple::create({ complex_cls, object_cls }); complex_cls->tp_mro = BoxedTuple::create({ complex_cls, object_cls });
...@@ -3810,7 +3811,6 @@ void setupRuntime() { ...@@ -3810,7 +3811,6 @@ void setupRuntime() {
pyston_getset_cls->finishInitialization(); pyston_getset_cls->finishInitialization();
attrwrapper_cls->finishInitialization(); attrwrapper_cls->finishInitialization();
dict_cls->finishInitialization(); dict_cls->finishInitialization();
file_cls->finishInitialization();
int_cls->finishInitialization(); int_cls->finishInitialization();
bool_cls->finishInitialization(); bool_cls->finishInitialization();
complex_cls->finishInitialization(); complex_cls->finishInitialization();
...@@ -3954,7 +3954,6 @@ void setupRuntime() { ...@@ -3954,7 +3954,6 @@ void setupRuntime() {
setupDict(); setupDict();
setupSet(); setupSet();
setupTuple(); setupTuple();
setupFile();
setupGenerator(); setupGenerator();
setupIter(); setupIter();
setupClassobj(); setupClassobj();
...@@ -4101,6 +4100,21 @@ void setupRuntime() { ...@@ -4101,6 +4100,21 @@ void setupRuntime() {
attrwrapperiter_cls->tp_iter = PyObject_SelfIter; attrwrapperiter_cls->tp_iter = PyObject_SelfIter;
attrwrapperiter_cls->tp_iternext = AttrWrapperIter::next_capi; attrwrapperiter_cls->tp_iternext = AttrWrapperIter::next_capi;
PyType_Ready(&PyFile_Type);
PyObject* sysin, *sysout, *syserr;
sysin = PyFile_FromFile(stdin, "<stdin>", "r", NULL);
sysout = PyFile_FromFile(stdout, "<stdout>", "w", _check_and_flush);
syserr = PyFile_FromFile(stderr, "<stderr>", "w", _check_and_flush);
RELEASE_ASSERT(!PyErr_Occurred(), "");
sys_module->giveAttr("stdout", sysout);
sys_module->giveAttr("stdin", sysin);
sys_module->giveAttr("stderr", syserr);
sys_module->giveAttr("__stdout__", sys_module->getattr(internStringMortal("stdout")));
sys_module->giveAttr("__stdin__", sys_module->getattr(internStringMortal("stdin")));
sys_module->giveAttr("__stderr__", sys_module->getattr(internStringMortal("stderr")));
setupBuiltins(); setupBuiltins();
_PyExc_Init(); _PyExc_Init();
setupThread(); setupThread();
...@@ -4117,6 +4131,7 @@ void setupRuntime() { ...@@ -4117,6 +4131,7 @@ void setupRuntime() {
PyType_Ready(&PyCObject_Type); PyType_Ready(&PyCObject_Type);
PyType_Ready(&PyDictProxy_Type); PyType_Ready(&PyDictProxy_Type);
initerrno(); initerrno();
init_sha(); init_sha();
init_sha256(); init_sha256();
...@@ -4213,7 +4228,6 @@ void teardownRuntime() { ...@@ -4213,7 +4228,6 @@ void teardownRuntime() {
teardownDict(); teardownDict();
teardownSet(); teardownSet();
teardownTuple(); teardownTuple();
teardownFile();
teardownDescr(); teardownDescr();
/* /*
...@@ -4233,7 +4247,6 @@ void teardownRuntime() { ...@@ -4233,7 +4247,6 @@ void teardownRuntime() {
clearAttrs(module_cls); clearAttrs(module_cls);
clearAttrs(dict_cls); clearAttrs(dict_cls);
clearAttrs(tuple_cls); clearAttrs(tuple_cls);
clearAttrs(file_cls);
decref(bool_cls); decref(bool_cls);
decref(int_cls); decref(int_cls);
...@@ -4246,7 +4259,6 @@ void teardownRuntime() { ...@@ -4246,7 +4259,6 @@ void teardownRuntime() {
decref(module_cls); decref(module_cls);
decref(dict_cls); decref(dict_cls);
decref(tuple_cls); decref(tuple_cls);
decref(file_cls);
ASSERT(None->nrefs == 1, "%ld", None->nrefs); ASSERT(None->nrefs == 1, "%ld", None->nrefs);
decref(None); decref(None);
......
...@@ -89,11 +89,11 @@ extern "C" BoxedString* EmptyString; ...@@ -89,11 +89,11 @@ extern "C" BoxedString* EmptyString;
extern "C" { extern "C" {
extern BoxedClass* object_cls, *type_cls, *bool_cls, *int_cls, *long_cls, *float_cls, *str_cls, *function_cls, extern BoxedClass* object_cls, *type_cls, *bool_cls, *int_cls, *long_cls, *float_cls, *str_cls, *function_cls,
*none_cls, *instancemethod_cls, *list_cls, *slice_cls, *module_cls, *dict_cls, *tuple_cls, *file_cls, *none_cls, *instancemethod_cls, *list_cls, *slice_cls, *module_cls, *dict_cls, *tuple_cls, *enumerate_cls,
*enumerate_cls, *xrange_cls, *member_descriptor_cls, *null_importer_cls, *method_cls, *closure_cls, *generator_cls, *xrange_cls, *member_descriptor_cls, *null_importer_cls, *method_cls, *closure_cls, *generator_cls, *complex_cls,
*complex_cls, *basestring_cls, *property_cls, *staticmethod_cls, *classmethod_cls, *attrwrapper_cls, *basestring_cls, *property_cls, *staticmethod_cls, *classmethod_cls, *attrwrapper_cls, *pyston_getset_cls,
*pyston_getset_cls, *capi_getset_cls, *builtin_function_or_method_cls, *set_cls, *frozenset_cls, *code_cls, *capi_getset_cls, *builtin_function_or_method_cls, *set_cls, *frozenset_cls, *code_cls, *frame_cls, *capifunc_cls,
*frame_cls, *capifunc_cls, *wrapperdescr_cls, *wrapperobject_cls; *wrapperdescr_cls, *wrapperobject_cls;
} }
#define unicode_cls (&PyUnicode_Type) #define unicode_cls (&PyUnicode_Type)
#define memoryview_cls (&PyMemoryView_Type) #define memoryview_cls (&PyMemoryView_Type)
......
...@@ -95,6 +95,7 @@ test_exceptions we are missing recursion-depth checking ...@@ -95,6 +95,7 @@ test_exceptions we are missing recursion-depth checking
test_extcall f(**kw) crashes if kw isn't a dict test_extcall f(**kw) crashes if kw isn't a dict
test_file2k we abort when you try to open() a directory test_file2k we abort when you try to open() a directory
test_file_eintr not sure test_file_eintr not sure
test_fileio [unknown]
test_fork1 [unknown] test_fork1 [unknown]
test_frozen [unknown] test_frozen [unknown]
test_ftplib [unknown] test_ftplib [unknown]
...@@ -186,7 +187,6 @@ test_site [unknown] ...@@ -186,7 +187,6 @@ test_site [unknown]
test_smtpnet [unknown] test_smtpnet [unknown]
test_socketserver [unknown] test_socketserver [unknown]
test_socket [unknown] test_socket [unknown]
test_softspace [unknown]
test_sort argument specification issue in listSort? test_sort argument specification issue in listSort?
test_sqlite [unknown] test_sqlite [unknown]
test_ssl [unknown] test_ssl [unknown]
......
...@@ -17,5 +17,5 @@ import subprocess ...@@ -17,5 +17,5 @@ import subprocess
subprocess.check_call(["sed", "-i", 's/\\(def test_digest.*\\)/\\1\\n return/', subprocess.check_call(["sed", "-i", 's/\\(def test_digest.*\\)/\\1\\n return/',
os.path.join(PYOPENSSL_DIR, "test", "test_crypto.py")]) os.path.join(PYOPENSSL_DIR, "test", "test_crypto.py")])
expected = [{'ran': 247, 'errors': 2}] expected = [{'ran': 247, 'errors': 1}]
run_test([NOSETESTS_EXE], cwd=PYOPENSSL_DIR, expected=expected) run_test([NOSETESTS_EXE], cwd=PYOPENSSL_DIR, expected=expected)
# expected: fail
# - I don't feel like implementing this right now
class C(object): class C(object):
def write(self, s): def write(self, s):
print "class write", repr(s) print "class write", repr(s)
......
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