Commit 09057fcb authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge branch 'django_dependencies'

parents 4e9effbf 9f8f77c1
......@@ -54,6 +54,7 @@
#define HAVE_SOCKADDR_STORAGE 1
#define HAVE_SOCKETPAIR 1
#define HAVE_GETPEERNAME 1
#define HAVE_STRFTIME 1
#define PY_FORMAT_LONG_LONG "ll"
#define PY_FORMAT_SIZE_T "z"
......
......@@ -407,6 +407,37 @@ def namedtuple(typename, field_names, verbose=False, rename=False):
return result
# Pyston change: use this hacky / slow? version of namedtuple while we work
# on exec support
def namedtuple(name, fields):
if isinstance(fields, str):
fields = fields.split()
assert isinstance(fields, list)
for f in fields:
assert isinstance(f, str)
class NamedTuple(object):
def __init__(self, *args):
assert len(args) == len(fields)
for i in xrange(len(fields)):
setattr(self, fields[i], args[i])
def __getitem__(self, idx):
assert 0 <= idx < len(fields)
return getattr(self, fields[idx])
def __repr__(self):
s = name + "("
first = True
for f in fields:
if not first:
s += ", "
first = False
s += "%s=%r" % (f, getattr(self, f))
s += ")"
return s
return NamedTuple
########################################################################
### Counter
......
......@@ -1092,6 +1092,18 @@ Done:
Py_DECREF(it);
return n;
}
extern "C" int PySequence_Contains(PyObject* seq, PyObject* ob) noexcept {
Py_ssize_t result;
if (PyType_HasFeature(seq->cls, Py_TPFLAGS_HAVE_SEQUENCE_IN)) {
PySequenceMethods* sqm = seq->cls->tp_as_sequence;
if (sqm != NULL && sqm->sq_contains != NULL)
return (*sqm->sq_contains)(seq, ob);
}
result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS);
return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
}
extern "C" PyObject* PyObject_CallFunction(PyObject* callable, const char* format, ...) noexcept {
va_list va;
PyObject* args;
......@@ -1153,7 +1165,7 @@ extern "C" int PyNumber_Check(PyObject* obj) noexcept {
assert(obj && obj->cls);
// Our check, since we don't currently fill in tp_as_number:
if (isSubclass(obj->cls, int_cls) || isSubclass(obj->cls, long_cls))
if (isSubclass(obj->cls, int_cls) || isSubclass(obj->cls, long_cls) || isSubclass(obj->cls, float_cls))
return true;
// The CPython check:
......
......@@ -24,29 +24,39 @@ Box* BoxedMethodDescriptor::__call__(BoxedMethodDescriptor* self, Box* obj, Boxe
assert(varargs->cls == tuple_cls);
assert(kwargs->cls == dict_cls);
if (!isSubclass(obj->cls, self->type))
raiseExcHelper(TypeError, "descriptor '%s' requires a '%s' object but received a '%s'", self->method->ml_name,
getFullNameOfClass(self->type).c_str(), getFullTypeName(obj).c_str());
int ml_flags = self->method->ml_flags;
int call_flags;
if (ml_flags & METH_CLASS) {
if (!isSubclass(obj->cls, type_cls))
raiseExcHelper(TypeError, "descriptor '%s' requires a type but received a '%s'", self->method->ml_name,
getFullTypeName(obj).c_str());
call_flags = ml_flags & (~METH_CLASS);
} else {
if (!isSubclass(obj->cls, self->type))
raiseExcHelper(TypeError, "descriptor '%s' requires a '%s' object but received a '%s'",
self->method->ml_name, getFullNameOfClass(self->type).c_str(), getFullTypeName(obj).c_str());
call_flags = ml_flags;
}
threading::GLPromoteRegion _gil_lock;
int ml_flags = self->method->ml_flags;
Box* rtn;
if (ml_flags == METH_NOARGS) {
if (call_flags == METH_NOARGS) {
assert(varargs->elts.size() == 0);
assert(kwargs->d.size() == 0);
rtn = (Box*)self->method->ml_meth(obj, NULL);
} else if (ml_flags == METH_VARARGS) {
} else if (call_flags == METH_VARARGS) {
assert(kwargs->d.size() == 0);
rtn = (Box*)self->method->ml_meth(obj, varargs);
} else if (ml_flags == (METH_VARARGS | METH_KEYWORDS)) {
} else if (call_flags == (METH_VARARGS | METH_KEYWORDS)) {
rtn = (Box*)((PyCFunctionWithKeywords)self->method->ml_meth)(obj, varargs, kwargs);
} else if (ml_flags == METH_O) {
} else if (call_flags == METH_O) {
assert(kwargs->d.size() == 0);
assert(varargs->elts.size() == 1);
rtn = (Box*)self->method->ml_meth(obj, varargs->elts[0]);
} else {
RELEASE_ASSERT(0, "0x%x", ml_flags);
RELEASE_ASSERT(0, "0x%x", call_flags);
}
checkAndThrowCAPIException();
......
......@@ -389,7 +389,8 @@ extern "C" PyObject* Py_InitModule4(const char* name, PyMethodDef* methods, cons
if (VERBOSITY())
printf("Loading method %s\n", methods->ml_name);
assert((methods->ml_flags & (~(METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O))) == 0);
RELEASE_ASSERT((methods->ml_flags & (~(METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O))) == 0, "%d",
methods->ml_flags);
module->giveAttr(methods->ml_name,
new BoxedCApiFunction(methods->ml_flags, passthrough, methods->ml_name, methods->ml_meth));
......
......@@ -16,6 +16,7 @@
#include "capi/typeobject.h"
#include "capi/types.h"
#include "runtime/classobj.h"
#include "runtime/objmodel.h"
namespace pyston {
......@@ -1607,11 +1608,8 @@ static int fill_classic_mro(PyObject* mro, PyObject* cls) {
if (PyList_Append(mro, cls) < 0)
return -1;
}
Py_FatalError("unimplemented");
// We should add multiple inheritance for old-style classes
#if 0
bases = ((PyClassObject*)cls)->cl_bases;
bases = ((BoxedClassobj*)cls)->bases;
assert(bases && PyTuple_Check(bases));
n = PyTuple_GET_SIZE(bases);
for (i = 0; i < n; i++) {
......@@ -1620,7 +1618,6 @@ static int fill_classic_mro(PyObject* mro, PyObject* cls) {
return -1;
}
return 0;
#endif
}
static PyObject* classic_mro(PyObject* cls) {
......
......@@ -144,10 +144,20 @@ public:
static Box* __get__(BoxedMethodDescriptor* self, Box* inst, Box* owner) {
RELEASE_ASSERT(self->cls == method_cls, "");
// CPython handles this differently: they create the equivalent of different BoxedMethodDescriptor
// objects but with different class objects, which define different __get__ and __call__ methods.
if (self->method->ml_flags & METH_CLASS)
return boxInstanceMethod(owner, self);
if (self->method->ml_flags & METH_STATIC)
Py_FatalError("unimplemented");
if (self->method->ml_flags & METH_COEXIST)
Py_FatalError("unimplemented");
if (inst == None)
return self;
// CPython apparently returns a "builtin_function_or_method" object
return boxInstanceMethod(inst, self);
else
return boxInstanceMethod(inst, self);
}
static Box* __call__(BoxedMethodDescriptor* self, Box* obj, BoxedTuple* varargs, Box** _args);
......
......@@ -451,10 +451,6 @@ extern "C" Py_ssize_t PySequence_Count(PyObject* o, PyObject* value) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PySequence_Contains(PyObject* o, PyObject* value) noexcept {
Py_FatalError("unimplemented");
}
extern "C" Py_ssize_t PySequence_Index(PyObject* o, PyObject* value) noexcept {
Py_FatalError("unimplemented");
}
......
......@@ -84,6 +84,15 @@ Box* classobjNew(Box* _cls, Box* _name, Box* _bases, Box** _args) {
raiseExcHelper(TypeError, "PyClass_New: bases must be a tuple");
BoxedTuple* bases = static_cast<BoxedTuple*>(_bases);
for (auto base : bases->elts) {
if (!PyClass_Check(base) && PyCallable_Check(base->cls)) {
Box* r = PyObject_CallFunctionObjArgs(base->cls, name, bases, dict, NULL);
if (!r)
throwCAPIException();
return r;
}
}
BoxedClassobj* made = new (cls) BoxedClassobj(name, bases);
made->giveAttr("__module__", boxString(getCurrentModule()->name()));
......
......@@ -1862,8 +1862,13 @@ extern "C" BoxedString* str(Box* obj) {
obj = callattrInternal(obj, &str_str, CLASS_ONLY, NULL, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
}
if (obj->cls != str_cls) {
raiseExcHelper(TypeError, "__str__ did not return a string!");
if (isSubclass(obj->cls, unicode_cls)) {
obj = PyUnicode_AsASCIIString(obj);
checkAndThrowCAPIException();
}
if (!isSubclass(obj->cls, str_cls)) {
raiseExcHelper(TypeError, "__str__ returned non-string (type %s)", obj->cls->tp_name);
}
return static_cast<BoxedString*>(obj);
}
......@@ -1874,8 +1879,13 @@ extern "C" BoxedString* repr(Box* obj) {
obj = callattrInternal(obj, &repr_str, CLASS_ONLY, NULL, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
if (obj->cls != str_cls) {
raiseExcHelper(TypeError, "__repr__ did not return a string!");
if (isSubclass(obj->cls, unicode_cls)) {
obj = PyUnicode_AsASCIIString(obj);
checkAndThrowCAPIException();
}
if (!isSubclass(obj->cls, str_cls)) {
raiseExcHelper(TypeError, "__repr__ returned non-string (type %s)", obj->cls->tp_name);
}
return static_cast<BoxedString*>(obj);
}
......@@ -1939,8 +1949,8 @@ extern "C" BoxedInt* hash(Box* obj) {
Box* hash = getclsattr_internal(obj, "__hash__", NULL);
if (hash == NULL) {
ASSERT(isUserDefined(obj->cls) || obj->cls == function_cls || obj->cls == object_cls
|| obj->cls == classobj_cls,
ASSERT(isUserDefined(obj->cls) || obj->cls == function_cls || obj->cls == object_cls || obj->cls == classobj_cls
|| obj->cls == module_cls,
"%s.__hash__", getTypeName(obj));
// TODO not the best way to handle this...
return static_cast<BoxedInt*>(boxInt((i64)obj));
......
......@@ -1214,7 +1214,10 @@ extern "C" Box* strLen(BoxedString* self) {
extern "C" Box* strStr(BoxedString* self) {
assert(isSubclass(self->cls, str_cls));
return self;
if (self->cls == str_cls)
return self;
return new BoxedString(self->s);
}
static bool _needs_escaping[256]
......@@ -1488,7 +1491,7 @@ extern "C" Box* strNew(BoxedClass* cls, Box* obj) {
assert(isSubclass(cls, str_cls));
Box* rtn = str(obj);
assert(rtn->cls == str_cls);
assert(isSubclass(rtn->cls, str_cls));
if (cls == str_cls)
return rtn;
......
......@@ -1927,6 +1927,10 @@ void setupRuntime() {
attrwrapper_cls->giveAttr("keys", new BoxedFunction(boxRTFunction((void*)AttrWrapper::keys, LIST, 1)));
attrwrapper_cls->giveAttr("values", new BoxedFunction(boxRTFunction((void*)AttrWrapper::values, LIST, 1)));
attrwrapper_cls->giveAttr("items", new BoxedFunction(boxRTFunction((void*)AttrWrapper::items, LIST, 1)));
// TODO: not quite right
attrwrapper_cls->giveAttr("iterkeys", attrwrapper_cls->getattr("keys"));
attrwrapper_cls->giveAttr("itervalues", attrwrapper_cls->getattr("values"));
attrwrapper_cls->giveAttr("iteritems", attrwrapper_cls->getattr("items"));
attrwrapper_cls->giveAttr("copy", new BoxedFunction(boxRTFunction((void*)AttrWrapper::copy, UNKNOWN, 1)));
attrwrapper_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)AttrWrapper::len, BOXED_INT, 1)));
attrwrapper_cls->giveAttr("__iter__", new BoxedFunction(boxRTFunction((void*)AttrWrapper::iter, UNKNOWN, 1)));
......
......@@ -6,3 +6,8 @@ print repr(datetime.time())
print datetime.datetime.__base__
print repr(datetime.datetime(1, 2, 3))
print str(datetime.timedelta(0))
# now() works on both the class and on its instances:
datetime.datetime.now().now()
print datetime.datetime(1924, 2, 3).strftime("%B %d, %Y - %X")
# __bases__ and __name__ not supported yet -- need to add a custom getattr() method for old style classes
class C():
pass
......@@ -166,3 +164,35 @@ try:
C.doesnt_exist
except AttributeError as e:
print e
class C():
pass
print type(C) # classobj
class D(C):
pass
print type(D) # classobj
# Inheriting from old + new style classes gives a new-style class
class E(C, object):
pass
print type(E) # type
class F(object, C):
pass
print type(F) # type
print type("aoeu", (str, object), {})
# ClassType has to defer to calling type(b) for the first non-oldstyle base
print type(ClassType("aoeu", (str, object), {}))
# Even if that is not a new-style class!
class MyCustomClass(object):
def __init__(self, *args, **kw):
print "init", args[:-1], kw
def __repr__(self):
return "<MCC>"
# type(MyCustomClass()) is MyCustomClass, which is callable, leading to another call to __init__
print ClassType("aoeu", (MyCustomClass(), ), {})
......@@ -99,3 +99,41 @@ print "hello world".rsplit(u'l')
with open(u"/dev/null", u"r") as f:
print f.read()
class CustomRepr(object):
def __init__(self, x):
self.x = x
def __str__(self):
return self.x
def __repr__(self):
return self.x
print repr(str(CustomRepr(u'')))
print repr(repr(CustomRepr(u'')))
try:
str(CustomRepr(u'\u0180'))
except Exception as e:
print type(e), e
try:
repr(CustomRepr(u'\u0180'))
except Exception as e:
print type(e), e
try:
str(CustomRepr(1))
except Exception as e:
print type(e), e
try:
repr(CustomRepr(1))
except Exception as e:
print type(e), e
class MyStr(str):
pass
print type(str(CustomRepr(MyStr("hi"))))
print type(MyStr("hi").__str__())
print type(str(MyStr("hi")))
# skip-if: True
# - this is blocking on some rewriter stuff
import urlparse
print urlparse.urlparse("http://www.dropbox.com")
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