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

Merge pull request #403 from undingen/fix_pip_search

misc fixes for running 'pip search'
parents 62f7f2f4 cc667893
......@@ -68,8 +68,6 @@ public:
uint8_t readByte() {
ensure(1);
RELEASE_ASSERT(end > start, "premature eof");
if (VERBOSITY("parsing") >= 2)
printf("readByte, now %d %d\n", start + 1, end);
return buf[start++];
}
uint16_t readShort() { return (readByte() << 8) | (readByte()); }
......@@ -101,16 +99,20 @@ AST_stmt* readASTStmt(BufferedReader* reader);
static std::string readString(BufferedReader* reader) {
int strlen = reader->readShort();
std::vector<char> chars;
llvm::SmallString<32> chars;
for (int i = 0; i < strlen; i++) {
chars.push_back(reader->readByte());
}
return std::string(chars.begin(), chars.end());
return chars.str().str();
}
InternedString BufferedReader::readAndInternString() {
std::string str = readString(this);
return intern_pool->get(std::move(str));
int strlen = readShort();
llvm::SmallString<32> chars;
for (int i = 0; i < strlen; i++) {
chars.push_back(readByte());
}
return intern_pool->get(chars.str());
}
void BufferedReader::readAndInternStringVector(std::vector<InternedString>& v) {
......
......@@ -447,7 +447,7 @@ extern "C" PyObject* PySequence_GetItem(PyObject* o, Py_ssize_t i) noexcept {
extern "C" PyObject* PySequence_GetSlice(PyObject* o, Py_ssize_t i1, Py_ssize_t i2) noexcept {
try {
// Not sure if this is really the same:
return getitem(o, new BoxedSlice(boxInt(i1), boxInt(i2), None));
return getitem(o, createSlice(boxInt(i1), boxInt(i2), None));
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
......
......@@ -59,7 +59,26 @@ static Box* classLookup(BoxedClassobj* cls, const std::string& attr) {
}
extern "C" int PyClass_IsSubclass(PyObject* klass, PyObject* base) noexcept {
Py_FatalError("unimplemented");
Py_ssize_t i, n;
if (klass == base)
return 1;
if (PyTuple_Check(base)) {
n = PyTuple_GET_SIZE(base);
for (i = 0; i < n; i++) {
if (PyClass_IsSubclass(klass, PyTuple_GET_ITEM(base, i)))
return 1;
}
return 0;
}
if (klass == NULL || !PyClass_Check(klass))
return 0;
BoxedClassobj* cp = (BoxedClassobj*)klass;
n = PyTuple_Size(cp->bases);
for (i = 0; i < n; i++) {
if (PyClass_IsSubclass(PyTuple_GetItem(cp->bases, i), base))
return 1;
}
return 0;
}
Box* classobjNew(Box* _cls, Box* _name, Box* _bases, Box** _args) {
......@@ -175,6 +194,58 @@ static Box* classobj_getattro(Box* cls, Box* attr) noexcept {
}
}
static const char* set_bases(PyClassObject* c, PyObject* v) {
Py_ssize_t i, n;
if (v == NULL || !PyTuple_Check(v))
return "__bases__ must be a tuple object";
n = PyTuple_Size(v);
for (i = 0; i < n; i++) {
PyObject* x = PyTuple_GET_ITEM(v, i);
if (!PyClass_Check(x))
return "__bases__ items must be classes";
if (PyClass_IsSubclass(x, (PyObject*)c))
return "a __bases__ item causes an inheritance cycle";
}
// Pyston change:
// set_slot(&c->cl_bases, v);
// set_attr_slots(c);
((BoxedClassobj*)c)->bases = (BoxedTuple*)v;
return "";
}
static void classobjSetattr(Box* _cls, Box* _attr, Box* _value) {
RELEASE_ASSERT(_cls->cls == classobj_cls, "");
BoxedClassobj* cls = static_cast<BoxedClassobj*>(_cls);
RELEASE_ASSERT(_attr->cls == str_cls, "");
BoxedString* attr = static_cast<BoxedString*>(_attr);
if (attr->s == "__bases__") {
const char* error_str = set_bases((PyClassObject*)cls, _value);
if (error_str && error_str[0] != '\0')
raiseExcHelper(TypeError, "%s", error_str);
cls->setattr("__bases__", _value, NULL);
return;
}
PyObject_GenericSetAttr(cls, _attr, _value);
checkAndThrowCAPIException();
}
static int classobj_setattro(Box* cls, Box* attr, Box* value) noexcept {
try {
if (value) {
classobjSetattr(cls, attr, value);
return 0;
} else {
RELEASE_ASSERT(0, "");
}
} catch (ExcInfo e) {
setCAPIException(e);
return -1;
}
}
Box* classobjStr(Box* _obj) {
if (!isSubclass(_obj->cls, classobj_cls)) {
raiseExcHelper(TypeError, "descriptor '__str__' requires a 'classobj' object but received an '%s'",
......@@ -433,6 +504,17 @@ static Box* instanceHash(BoxedInstance* inst) {
}
}
Box* instanceCall(Box* _inst, Box* _args, Box* _kwargs) {
assert(_inst->cls == instance_cls);
BoxedInstance* inst = static_cast<BoxedInstance*>(_inst);
Box* call_func = _instanceGetattribute(inst, boxStrConstant("__call__"), false);
if (!call_func)
raiseExcHelper(AttributeError, "%s instance has no __call__ method", inst->inst_cls->name->s.c_str());
return runtimeCall(call_func, ArgPassSpec(0, 0, true, true), _args, _kwargs, NULL, NULL, NULL);
}
void setupClassobj() {
classobj_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedClassobj::gcHandler,
offsetof(BoxedClassobj, attrs), 0, sizeof(BoxedClassobj), false, "classobj");
......@@ -448,11 +530,13 @@ void setupClassobj() {
classobj_cls->giveAttr("__getattribute__",
new BoxedFunction(boxRTFunction((void*)classobjGetattribute, UNKNOWN, 2)));
classobj_cls->giveAttr("__setattr__", new BoxedFunction(boxRTFunction((void*)classobjSetattr, UNKNOWN, 3)));
classobj_cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)classobjStr, STR, 1)));
classobj_cls->giveAttr("__dict__", dict_descr);
classobj_cls->freeze();
classobj_cls->tp_getattro = classobj_getattro;
classobj_cls->tp_setattro = classobj_setattro;
instance_cls->giveAttr("__getattribute__",
......@@ -467,6 +551,8 @@ void setupClassobj() {
instance_cls->giveAttr("__delitem__", new BoxedFunction(boxRTFunction((void*)instanceDelitem, UNKNOWN, 2)));
instance_cls->giveAttr("__contains__", new BoxedFunction(boxRTFunction((void*)instanceContains, UNKNOWN, 2)));
instance_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)instanceHash, UNKNOWN, 1)));
instance_cls->giveAttr("__call__",
new BoxedFunction(boxRTFunction((void*)instanceCall, UNKNOWN, 1, 0, true, true)));
instance_cls->freeze();
instance_cls->tp_getattro = instance_getattro;
......
......@@ -785,10 +785,11 @@ extern "C" int PyList_SetSlice(PyObject* a, Py_ssize_t ilow, Py_ssize_t ihigh, P
ASSERT(isSubclass(l->cls, list_cls), "%s", l->cls->tp_name);
try {
BoxedSlice* slice = (BoxedSlice*)createSlice(boxInt(ilow), boxInt(ihigh), None);
if (v)
listSetitemSlice(l, new BoxedSlice(boxInt(ilow), boxInt(ihigh), None), v);
listSetitemSlice(l, slice, v);
else
listDelitemSlice(l, new BoxedSlice(boxInt(ilow), boxInt(ihigh), None));
listDelitemSlice(l, slice);
return 0;
} catch (ExcInfo e) {
setCAPIException(e);
......
......@@ -2350,6 +2350,42 @@ overflow1:
return NULL;
}
static PyObject* string_zfill(PyObject* self, PyObject* args) {
Py_ssize_t fill;
PyObject* s;
char* p;
Py_ssize_t width;
if (!PyArg_ParseTuple(args, "n:zfill", &width))
return NULL;
if (PyString_GET_SIZE(self) >= width) {
if (PyString_CheckExact(self)) {
Py_INCREF(self);
return (PyObject*)self;
} else
return PyString_FromStringAndSize(PyString_AS_STRING(self), PyString_GET_SIZE(self));
}
fill = width - PyString_GET_SIZE(self);
// Pyston change:
// s = pad(self, fill, 0, '0');
s = pad((BoxedString*)self, boxInt(width), boxString("0"), JUST_RIGHT);
if (s == NULL)
return NULL;
p = PyString_AS_STRING(s);
if (p[fill] == '+' || p[fill] == '-') {
/* move sign to beginning of string */
p[0] = p[fill];
p[fill] = '0';
}
return (PyObject*)s;
}
static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, const void** ptr) noexcept {
RELEASE_ASSERT(index == 0, "");
// I think maybe this can just be a non-release assert? shouldn't be able to call this with
......@@ -2407,6 +2443,7 @@ static PyMethodDef string_methods[] = {
{ "rfind", (PyCFunction)string_rfind, METH_VARARGS, NULL },
{ "expandtabs", (PyCFunction)string_expandtabs, METH_VARARGS, NULL },
{ "splitlines", (PyCFunction)string_splitlines, METH_VARARGS, NULL },
{ "zfill", (PyCFunction)string_zfill, METH_VARARGS, NULL },
};
void setupStr() {
......
......@@ -50,6 +50,11 @@ class E():
print "len"
return self.n
def __call__(self):
def f(a):
print "f", a
return f
e = E(1)
print e
print e.n
......@@ -57,6 +62,7 @@ print e.foo()
print e[1]
print e[1:2]
print len(e)
print e()("test")
def str2():
return "str2"
......@@ -204,3 +210,16 @@ class MyCustomClass(object):
# type(MyCustomClass()) is MyCustomClass, which is callable, leading to another call to __init__
print ClassType("aoeu", (MyCustomClass(), ), {})
class D():
def test(self):
return "D.test"
class LateSubclassing():
def __init__(self):
LateSubclassing.__bases__ = (C, D)
print LateSubclassing().test()
print issubclass(LateSubclassing, C)
print issubclass(LateSubclassing, D)
print issubclass(LateSubclassing, E)
......@@ -155,3 +155,5 @@ print "a.b.c.d".rpartition('.')
print 'ab c\n\nde fg\rkl\r\n'.splitlines()
print 'ab c\n\nde fg\rkl\r\n'.splitlines(True)
print "1".zfill(3), "+1".zfill(3), "-1".zfill(3), "0".zfill(3)
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