Commit 0e28b43b authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #376 from undingen/virtualenv_fixes4

Implement further changes required for virtualenv
parents 3a9e87d7 ba798933
......@@ -23,6 +23,41 @@ PyObject * _do_string_format(PyObject *self, PyObject *args, PyObject *kwargs) {
return do_string_format(self, args, kwargs);
}
PyObject *
string_count(PyStringObject *self, PyObject *args)
{
PyObject *sub_obj;
const char *str = PyString_AS_STRING(self), *sub;
Py_ssize_t sub_len;
Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end))
return NULL;
if (PyString_Check(sub_obj)) {
sub = PyString_AS_STRING(sub_obj);
sub_len = PyString_GET_SIZE(sub_obj);
}
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(sub_obj)) {
Py_ssize_t count;
count = PyUnicode_Count((PyObject *)self, sub_obj, start, end);
if (count == -1)
return NULL;
else
return PyInt_FromSsize_t(count);
}
#endif
else if (PyObject_AsCharBuffer(sub_obj, &sub, &sub_len))
return NULL;
ADJUST_INDICES(start, end, PyString_GET_SIZE(self));
return PyInt_FromSsize_t(
stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
);
}
PyObject * string_split(PyStringObject *self, PyObject *args)
{
Py_ssize_t len = PyString_GET_SIZE(self), n;
......@@ -130,6 +165,20 @@ string_find(PyStringObject *self, PyObject *args)
return PyInt_FromSsize_t(result);
}
PyObject *
string_index(PyStringObject *self, PyObject *args)
{
Py_ssize_t result = string_find_internal(self, args, +1);
if (result == -2)
return NULL;
if (result == -1) {
PyErr_SetString(PyExc_ValueError,
"substring not found");
return NULL;
}
return PyInt_FromSsize_t(result);
}
PyObject*
string_splitlines(PyStringObject *self, PyObject *args)
{
......
......@@ -1839,9 +1839,14 @@ public:
jend->target = end;
curblock->connectTo(end);
}
curblock = end;
cfg->placeBlock(end);
if (end->predecessors.size() == 0) {
delete end;
curblock = NULL;
} else {
curblock = end;
cfg->placeBlock(end);
}
return true;
}
......
......@@ -158,6 +158,11 @@ static int main(int argc, char** argv) {
module_search_path = split_str.second;
}
if (!fn) {
// if we are in repl or command mode prepend "" to the path
prependToSysPath("");
}
if (!Py_NoSiteFlag) {
try {
std::string module_name = "site";
......
......@@ -47,6 +47,39 @@ extern "C" Box* boolNew(Box* cls, Box* val) {
return boxBool(b);
}
extern "C" Box* boolAnd(BoxedBool* lhs, BoxedBool* rhs) {
if (lhs->cls != bool_cls)
raiseExcHelper(TypeError, "descriptor '__and__' requires a 'bool' object but received a '%s'",
getTypeName(lhs));
if (rhs->cls != bool_cls)
return NotImplemented;
return boxBool(lhs->n && rhs->n);
}
extern "C" Box* boolOr(BoxedBool* lhs, BoxedBool* rhs) {
if (lhs->cls != bool_cls)
raiseExcHelper(TypeError, "descriptor '__or__' requires a 'bool' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != bool_cls)
return NotImplemented;
return boxBool(lhs->n || rhs->n);
}
extern "C" Box* boolXor(BoxedBool* lhs, BoxedBool* rhs) {
if (lhs->cls != bool_cls)
raiseExcHelper(TypeError, "descriptor '__xor__' requires a 'bool' object but received a '%s'",
getTypeName(lhs));
if (rhs->cls != bool_cls)
return NotImplemented;
return boxBool(lhs->n ^ rhs->n);
}
void setupBool() {
bool_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)boolNonzero, BOXED_BOOL, 1)));
bool_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)boolRepr, STR, 1)));
......@@ -55,6 +88,9 @@ void setupBool() {
bool_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)boolNew, UNKNOWN, 2, 1, false, false), { None }));
bool_cls->giveAttr("__and__", new BoxedFunction(boxRTFunction((void*)boolAnd, BOXED_BOOL, 2)));
bool_cls->giveAttr("__or__", new BoxedFunction(boxRTFunction((void*)boolOr, BOXED_BOOL, 2)));
bool_cls->giveAttr("__xor__", new BoxedFunction(boxRTFunction((void*)boolXor, BOXED_BOOL, 2)));
bool_cls->freeze();
......
......@@ -606,6 +606,171 @@ static PyObject* close_the_file(BoxedFile* f) {
Py_RETURN_NONE;
}
/* Our very own off_t-like type, 64-bit if possible */
#if !defined(HAVE_LARGEFILE_SUPPORT)
typedef off_t Py_off_t;
#elif SIZEOF_OFF_T >= 8
typedef off_t Py_off_t;
#elif SIZEOF_FPOS_T >= 8
typedef fpos_t Py_off_t;
#else
#error "Large file support, but neither off_t nor fpos_t is large enough."
#endif
/* a portable fseek() function
return 0 on success, non-zero on failure (with errno set) */
static int _portable_fseek(FILE* fp, Py_off_t offset, int whence) {
#if !defined(HAVE_LARGEFILE_SUPPORT)
return fseek(fp, offset, whence);
#elif defined(HAVE_FSEEKO) && SIZEOF_OFF_T >= 8
return fseeko(fp, offset, whence);
#elif defined(HAVE_FSEEK64)
return fseek64(fp, offset, whence);
#elif defined(__BEOS__)
return _fseek(fp, offset, whence);
#elif SIZEOF_FPOS_T >= 8
/* lacking a 64-bit capable fseek(), use a 64-bit capable fsetpos()
and fgetpos() to implement fseek()*/
fpos_t pos;
switch (whence) {
case SEEK_END:
#ifdef MS_WINDOWS
fflush(fp);
if (_lseeki64(fileno(fp), 0, 2) == -1)
return -1;
#else
if (fseek(fp, 0, SEEK_END) != 0)
return -1;
#endif
/* fall through */
case SEEK_CUR:
if (fgetpos(fp, &pos) != 0)
return -1;
offset += pos;
break;
/* case SEEK_SET: break; */
}
return fsetpos(fp, &offset);
#else
#error "Large file support, but no way to fseek."
#endif
}
static void drop_readahead(BoxedFile* f) {
if (f->f_buf != NULL) {
PyMem_Free(f->f_buf);
f->f_buf = NULL;
}
}
static PyObject* file_seek(BoxedFile* f, PyObject* args) {
int whence;
int ret;
Py_off_t offset;
PyObject* offobj, *off_index;
if (f->f_fp == NULL)
return err_closed();
drop_readahead(f);
whence = 0;
if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
return NULL;
off_index = PyNumber_Index(offobj);
if (!off_index) {
if (!PyFloat_Check(offobj))
return NULL;
/* Deprecated in 2.6 */
PyErr_Clear();
if (PyErr_WarnEx(PyExc_DeprecationWarning, "integer argument expected, got float", 1) < 0)
return NULL;
off_index = offobj;
Py_INCREF(offobj);
}
#if !defined(HAVE_LARGEFILE_SUPPORT)
offset = PyInt_AsLong(off_index);
#else
offset = PyLong_Check(off_index) ? PyLong_AsLongLong(off_index) : PyInt_AsLong(off_index);
#endif
Py_DECREF(off_index);
if (PyErr_Occurred())
return NULL;
FILE_BEGIN_ALLOW_THREADS(f)
errno = 0;
ret = _portable_fseek(f->f_fp, offset, whence);
FILE_END_ALLOW_THREADS(f)
if (ret != 0) {
PyErr_SetFromErrno(PyExc_IOError);
clearerr(f->f_fp);
return NULL;
}
f->f_skipnextlf = 0;
Py_INCREF(Py_None);
return Py_None;
}
/* a portable ftell() function
Return -1 on failure with errno set appropriately, current file
position on success */
static Py_off_t _portable_ftell(FILE* fp) {
#if !defined(HAVE_LARGEFILE_SUPPORT)
return ftell(fp);
#elif defined(HAVE_FTELLO) && SIZEOF_OFF_T >= 8
return ftello(fp);
#elif defined(HAVE_FTELL64)
return ftell64(fp);
#elif SIZEOF_FPOS_T >= 8
fpos_t pos;
if (fgetpos(fp, &pos) != 0)
return -1;
return pos;
#else
#error "Large file support, but no way to ftell."
#endif
}
static PyObject* file_tell(BoxedFile* f) {
Py_off_t pos;
if (f->f_fp == NULL)
return err_closed();
FILE_BEGIN_ALLOW_THREADS(f)
errno = 0;
pos = _portable_ftell(f->f_fp);
FILE_END_ALLOW_THREADS(f)
if (pos == -1) {
PyErr_SetFromErrno(PyExc_IOError);
clearerr(f->f_fp);
return NULL;
}
if (f->f_skipnextlf) {
int c;
c = GETC(f->f_fp);
if (c == '\n') {
f->f_newlinetypes |= NEWLINE_CRLF;
pos++;
f->f_skipnextlf = 0;
} else if (c != EOF)
ungetc(c, f->f_fp);
}
#if !defined(HAVE_LARGEFILE_SUPPORT)
return PyInt_FromLong(pos);
#else
return PyLong_FromLongLong(pos);
#endif
}
Box* fileTell(BoxedFile* f) {
if (!isSubclass(f->cls, file_cls))
raiseExcHelper(TypeError, "descriptor 'tell' requires a 'file' object but received a '%s'", getTypeName(f));
auto rtn = file_tell(f);
checkAndThrowCAPIException();
return rtn;
}
Box* fileClose(BoxedFile* self) {
assert(self->cls == file_cls);
......@@ -1074,6 +1239,18 @@ static PyObject* file_isatty(BoxedFile* f) noexcept {
return PyBool_FromLong(res);
}
PyDoc_STRVAR(seek_doc, "seek(offset[, whence]) -> None. Move to new file position.\n"
"\n"
"Argument offset is a byte count. Optional argument whence defaults to\n"
"0 (offset from start of file, offset should be >= 0); other values are 1\n"
"(move relative to current position, positive or negative), and 2 (move\n"
"relative to end of file, usually negative, although many platforms allow\n"
"seeking beyond the end of a file). If the file is opened in text mode,\n"
"only offsets returned by tell() are legal. Use of other offsets causes\n"
"undefined behavior."
"\n"
"Note that not all file objects are seekable.");
PyDoc_STRVAR(readlines_doc, "readlines([size]) -> list of strings, each a line from the file.\n"
"\n"
"Call readline() repeatedly and return a list of the lines so read.\n"
......@@ -1083,6 +1260,7 @@ PyDoc_STRVAR(readlines_doc, "readlines([size]) -> list of strings, each a line f
PyDoc_STRVAR(isatty_doc, "isatty() -> true or false. True if the file is connected to a tty device.");
PyMethodDef file_methods[] = {
{ "seek", (PyCFunction)file_seek, METH_VARARGS, seek_doc },
{ "readlines", (PyCFunction)file_readlines, METH_VARARGS, readlines_doc },
{ "isatty", (PyCFunction)file_isatty, METH_NOARGS, isatty_doc },
};
......@@ -1119,6 +1297,7 @@ void setupFile() {
file_cls->giveAttr("__hasnext__", new BoxedFunction(boxRTFunction((void*)fileIterHasNext, BOXED_BOOL, 1)));
file_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)fileIterNext, STR, 1)));
file_cls->giveAttr("tell", new BoxedFunction(boxRTFunction((void*)fileTell, UNKNOWN, 1)));
file_cls->giveAttr("softspace",
new BoxedMemberDescriptor(BoxedMemberDescriptor::INT, offsetof(BoxedFile, f_softspace), false));
......
......@@ -589,12 +589,29 @@ Box* listCount(BoxedList* self, Box* elt) {
return boxInt(count);
}
Box* listIndex(BoxedList* self, Box* elt) {
Box* listIndex(BoxedList* self, Box* elt, BoxedInt* _start, Box** args) {
LOCK_REGION(self->lock.asRead());
int size = self->size;
BoxedInt* _stop = (BoxedInt*)args[0];
RELEASE_ASSERT(!_start || _start->cls == int_cls, "");
RELEASE_ASSERT(!_stop || _stop->cls == int_cls, "");
for (int i = 0; i < size; i++) {
int64_t start = _start ? _start->n : 0;
int64_t stop = _stop ? _stop->n : self->size;
if (start < 0) {
start += self->size;
if (start < 0)
start = 0;
}
if (stop < 0) {
stop += self->size;
if (stop < 0)
stop = 0;
}
for (int64_t i = start; i < stop; i++) {
Box* e = self->elts->elts[i];
Box* cmp = compareInternal(e, elt, AST_TYPE::Eq, NULL);
bool b = nonzero(cmp);
......@@ -840,7 +857,8 @@ void setupList() {
new BoxedFunction(boxRTFunction((void*)listInit, UNKNOWN, 2, 1, false, false), { None }));
list_cls->giveAttr("count", new BoxedFunction(boxRTFunction((void*)listCount, BOXED_INT, 2)));
list_cls->giveAttr("index", new BoxedFunction(boxRTFunction((void*)listIndex, BOXED_INT, 2)));
list_cls->giveAttr(
"index", new BoxedFunction(boxRTFunction((void*)listIndex, BOXED_INT, 4, 2, false, false), { NULL, NULL }));
list_cls->giveAttr("remove", new BoxedFunction(boxRTFunction((void*)listRemove, NONE, 2)));
list_cls->giveAttr("reverse", new BoxedFunction(boxRTFunction((void*)listReverse, NONE, 1)));
list_cls->freeze();
......
......@@ -66,6 +66,11 @@ Box* setiteratorNext(BoxedSetIterator* self) {
return self->next();
}
Box* setiteratorIter(BoxedSetIterator* self) {
assert(self->cls == set_iterator_cls);
return self;
}
Box* setAdd2(Box* _self, Box* b) {
assert(_self->cls == set_cls || _self->cls == frozenset_cls);
BoxedSet* self = static_cast<BoxedSet*>(_self);
......@@ -247,6 +252,29 @@ Box* setUnion(BoxedSet* self, BoxedTuple* args) {
return rtn;
}
static BoxedSet* setIntersection2(BoxedSet* self, Box* container) {
assert(self->cls == set_cls);
BoxedSet* rtn = new BoxedSet();
for (auto elt : container->pyElements()) {
if (self->s.count(elt))
rtn->s.insert(elt);
}
return rtn;
}
Box* setIntersection(BoxedSet* self, BoxedTuple* args) {
if (!isSubclass(self->cls, set_cls))
raiseExcHelper(TypeError, "descriptor 'intersection' requires a 'set' object but received a '%s'",
getTypeName(self));
BoxedSet* rtn = self;
for (auto container : args->pyElements()) {
rtn = setIntersection2(rtn, container);
}
return rtn;
}
Box* setCopy(BoxedSet* self) {
assert(self->cls == set_cls);
......@@ -264,6 +292,18 @@ Box* setNonzero(BoxedSet* self) {
return boxBool(self->s.size());
}
Box* setHash(BoxedSet* self) {
RELEASE_ASSERT(isSubclass(self->cls, frozenset_cls), "");
int64_t rtn = 1927868237L;
for (Box* e : self->s) {
BoxedInt* h = hash(e);
assert(isSubclass(h->cls, int_cls));
rtn ^= h->n + 0x9e3779b9 + (rtn << 6) + (rtn >> 2);
}
return boxInt(rtn);
}
} // namespace set
......@@ -272,6 +312,8 @@ using namespace pyston::set;
void setupSet() {
set_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &setIteratorGCHandler, 0, 0, sizeof(BoxedSet),
false, "setiterator");
set_iterator_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)setiteratorIter, typeFromClass(set_iterator_cls), 1)));
set_iterator_cls->giveAttr("__hasnext__",
new BoxedFunction(boxRTFunction((void*)setiteratorHasnext, BOXED_BOOL, 1)));
set_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)setiteratorNext, UNKNOWN, 1)));
......@@ -331,12 +373,16 @@ void setupSet() {
set_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)setNonzero, BOXED_BOOL, 1)));
frozenset_cls->giveAttr("__nonzero__", set_cls->getattr("__nonzero__"));
frozenset_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)setHash, BOXED_INT, 1)));
set_cls->giveAttr("add", new BoxedFunction(boxRTFunction((void*)setAdd, NONE, 2)));
set_cls->giveAttr("remove", new BoxedFunction(boxRTFunction((void*)setRemove, NONE, 2)));
set_cls->giveAttr("clear", new BoxedFunction(boxRTFunction((void*)setClear, NONE, 1)));
set_cls->giveAttr("update", new BoxedFunction(boxRTFunction((void*)setUpdate, NONE, 1, 0, true, false)));
set_cls->giveAttr("union", new BoxedFunction(boxRTFunction((void*)setUnion, UNKNOWN, 1, 0, true, false)));
set_cls->giveAttr("intersection",
new BoxedFunction(boxRTFunction((void*)setIntersection, UNKNOWN, 1, 0, true, false)));
set_cls->giveAttr("copy", new BoxedFunction(boxRTFunction((void*)setCopy, UNKNOWN, 1)));
......
......@@ -35,9 +35,11 @@
#include "runtime/types.h"
#include "runtime/util.h"
extern "C" PyObject* string_count(PyStringObject* self, PyObject* args) noexcept;
extern "C" PyObject* string_split(PyStringObject* self, PyObject* args) noexcept;
extern "C" PyObject* string_rsplit(PyStringObject* self, PyObject* args) noexcept;
extern "C" PyObject* string_find(PyStringObject* self, PyObject* args) noexcept;
extern "C" PyObject* string_index(PyStringObject* self, PyObject* args) noexcept;
extern "C" PyObject* string_rfind(PyStringObject* self, PyObject* args) noexcept;
extern "C" PyObject* string_splitlines(PyStringObject* self, PyObject* args) noexcept;
......@@ -2080,8 +2082,8 @@ Box* strEncode(BoxedString* self, Box* encoding, Box* error) {
if (error_str && error_str->cls != str_cls)
raiseExcHelper(TypeError, "encode() argument 2 must be string, not '%s'", getTypeName(error_str));
Box* result
= PyCodec_Encode(self, encoding_str ? encoding_str->s.c_str() : NULL, error_str ? error_str->s.c_str() : NULL);
Box* result = PyCodec_Encode(self, encoding_str ? encoding_str->s.c_str() : PyUnicode_GetDefaultEncoding(),
error_str ? error_str->s.c_str() : NULL);
checkAndThrowCAPIException();
return result;
}
......@@ -2160,48 +2162,6 @@ Box* strIter(BoxedString* self) {
return new BoxedStringIterator(self);
}
int64_t strCount2Unboxed(BoxedString* self, Box* elt) {
assert(isSubclass(self->cls, str_cls));
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
const std::string& s = self->s;
const std::string& pattern = static_cast<BoxedString*>(elt)->s;
int found = 0;
size_t start = 0;
while (start < s.size()) {
size_t next = s.find(pattern, start);
if (next == std::string::npos)
break;
found++;
start = next + pattern.size();
}
return found;
}
Box* strCount2(BoxedString* self, Box* elt) {
return boxInt(strCount2Unboxed(self, elt));
}
Box* strIndex(BoxedString* self, Box* elt) {
assert(isSubclass(self->cls, str_cls));
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
const std::string& s = self->s;
const std::string& pattern = static_cast<BoxedString*>(elt)->s;
size_t idx = s.find(pattern, 0);
if (idx == std::string::npos)
raiseExcHelper(ValueError, "substring not found");
return boxInt(idx);
}
extern "C" PyObject* PyString_FromString(const char* s) noexcept {
return boxStrConstant(s);
}
......@@ -2434,9 +2394,11 @@ void strDestructor(Box* b) {
}
static PyMethodDef string_methods[] = {
{ "count", (PyCFunction)string_count, METH_VARARGS, NULL },
{ "split", (PyCFunction)string_split, METH_VARARGS, NULL },
{ "rsplit", (PyCFunction)string_rsplit, METH_VARARGS, NULL },
{ "find", (PyCFunction)string_find, METH_VARARGS, NULL },
{ "index", (PyCFunction)string_index, METH_VARARGS, NULL },
{ "rfind", (PyCFunction)string_rfind, METH_VARARGS, NULL },
{ "expandtabs", (PyCFunction)string_expandtabs, METH_VARARGS, NULL },
{ "splitlines", (PyCFunction)string_splitlines, METH_VARARGS, NULL },
......@@ -2534,11 +2496,6 @@ void setupStr() {
str_cls->giveAttr(md.ml_name, new BoxedMethodDescriptor(&md, str_cls));
}
CLFunction* count = boxRTFunction((void*)strCount2Unboxed, INT, 2);
addRTFunction(count, (void*)strCount2, BOXED_INT);
str_cls->giveAttr("count", new BoxedFunction(count));
str_cls->giveAttr("index", new BoxedFunction(boxRTFunction((void*)strIndex, BOXED_INT, 2)));
str_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)strNew, UNKNOWN, 2, 1, false, false),
{ boxStrConstant("") }));
......
......@@ -30,6 +30,12 @@ print hash(1) == hash(True)
print isinstance(True, int)
print isinstance(False, int)
for lhs in (True, False):
for rhs in (True, False):
print lhs | rhs
print lhs & rhs
print lhs ^ rhs
print range(False, True, True)
print abs(True), abs(False)
......
......@@ -49,7 +49,12 @@ except IOError as e:
print str(e)
f = open("/dev/null", "w")
print f.tell()
print f.write("hello world")
f.softspace = 0
print f.tell()
print f.seek(0)
print f.write("H")
print f.tell()
print f.flush()
print f.close()
......@@ -53,6 +53,15 @@ for i in xrange(5):
list_index = [1, 2, 3, 4, 5]
for i in xrange(1, 6):
assert list_index.index(i) == i-1
try:
print list_index.index(i, 3, 4)
except ValueError as e:
print e
try:
print list_index.index(i, -1, -1)
except ValueError as e:
print e
assert list_index.index(3) == 2
assert [1, '2'].index('2') == 1
......
......@@ -5,3 +5,11 @@ def f():
break
break
f()
def f2(x):
while x:
return 1
else:
return 2
print f2(1)
......@@ -80,8 +80,8 @@ s2 = s.copy()
s.add(1)
print s, s2
s1 = set([3])
s2 = set([1])
print sorted(s1.union(s2))
print sorted(s1.union(range(5, 7)))
print s2.union([], [], [], [])
s1 = set([3, 5])
s2 = set([1, 5])
print sorted(s1.union(s2)), sorted(s1.intersection(s2))
print sorted(s1.union(range(5, 7))), sorted(s1.intersection(range(5, 7)))
print sorted(s2.union([], [], [], [])), sorted(s2.intersection())
......@@ -38,6 +38,8 @@ for c in "hello world":
for c in "hello world":
print c, "hello world".count(c)
print c, "hello world".count(c, 1, 2)
print c, "hello world".count(c, 2, 5)
for i in xrange(1, 10):
for j in xrange(1, 4):
......@@ -132,6 +134,8 @@ for c in "hello world":
gc.collect()
print "hello world".index("world")
print "hello world".index("world", 1, 30)
print "hello world".index("l", 3)
try:
print "hello world".index("goodbye")
except:
......
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