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

Merge branch 'django_dependencies'

parents 4e9effbf 9f8f77c1
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#define HAVE_SOCKADDR_STORAGE 1 #define HAVE_SOCKADDR_STORAGE 1
#define HAVE_SOCKETPAIR 1 #define HAVE_SOCKETPAIR 1
#define HAVE_GETPEERNAME 1 #define HAVE_GETPEERNAME 1
#define HAVE_STRFTIME 1
#define PY_FORMAT_LONG_LONG "ll" #define PY_FORMAT_LONG_LONG "ll"
#define PY_FORMAT_SIZE_T "z" #define PY_FORMAT_SIZE_T "z"
......
...@@ -407,6 +407,37 @@ def namedtuple(typename, field_names, verbose=False, rename=False): ...@@ -407,6 +407,37 @@ def namedtuple(typename, field_names, verbose=False, rename=False):
return result 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 ### Counter
......
...@@ -1092,6 +1092,18 @@ Done: ...@@ -1092,6 +1092,18 @@ Done:
Py_DECREF(it); Py_DECREF(it);
return n; 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 { extern "C" PyObject* PyObject_CallFunction(PyObject* callable, const char* format, ...) noexcept {
va_list va; va_list va;
PyObject* args; PyObject* args;
...@@ -1153,7 +1165,7 @@ extern "C" int PyNumber_Check(PyObject* obj) noexcept { ...@@ -1153,7 +1165,7 @@ extern "C" int PyNumber_Check(PyObject* obj) noexcept {
assert(obj && obj->cls); assert(obj && obj->cls);
// Our check, since we don't currently fill in tp_as_number: // 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; return true;
// The CPython check: // The CPython check:
......
...@@ -24,29 +24,39 @@ Box* BoxedMethodDescriptor::__call__(BoxedMethodDescriptor* self, Box* obj, Boxe ...@@ -24,29 +24,39 @@ Box* BoxedMethodDescriptor::__call__(BoxedMethodDescriptor* self, Box* obj, Boxe
assert(varargs->cls == tuple_cls); assert(varargs->cls == tuple_cls);
assert(kwargs->cls == dict_cls); assert(kwargs->cls == dict_cls);
if (!isSubclass(obj->cls, self->type)) int ml_flags = self->method->ml_flags;
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 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; threading::GLPromoteRegion _gil_lock;
int ml_flags = self->method->ml_flags;
Box* rtn; Box* rtn;
if (ml_flags == METH_NOARGS) { if (call_flags == METH_NOARGS) {
assert(varargs->elts.size() == 0); assert(varargs->elts.size() == 0);
assert(kwargs->d.size() == 0); assert(kwargs->d.size() == 0);
rtn = (Box*)self->method->ml_meth(obj, NULL); 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); assert(kwargs->d.size() == 0);
rtn = (Box*)self->method->ml_meth(obj, varargs); 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); 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(kwargs->d.size() == 0);
assert(varargs->elts.size() == 1); assert(varargs->elts.size() == 1);
rtn = (Box*)self->method->ml_meth(obj, varargs->elts[0]); rtn = (Box*)self->method->ml_meth(obj, varargs->elts[0]);
} else { } else {
RELEASE_ASSERT(0, "0x%x", ml_flags); RELEASE_ASSERT(0, "0x%x", call_flags);
} }
checkAndThrowCAPIException(); checkAndThrowCAPIException();
......
...@@ -389,7 +389,8 @@ extern "C" PyObject* Py_InitModule4(const char* name, PyMethodDef* methods, cons ...@@ -389,7 +389,8 @@ extern "C" PyObject* Py_InitModule4(const char* name, PyMethodDef* methods, cons
if (VERBOSITY()) if (VERBOSITY())
printf("Loading method %s\n", methods->ml_name); 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, module->giveAttr(methods->ml_name,
new BoxedCApiFunction(methods->ml_flags, passthrough, methods->ml_name, methods->ml_meth)); new BoxedCApiFunction(methods->ml_flags, passthrough, methods->ml_name, methods->ml_meth));
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "capi/typeobject.h" #include "capi/typeobject.h"
#include "capi/types.h" #include "capi/types.h"
#include "runtime/classobj.h"
#include "runtime/objmodel.h" #include "runtime/objmodel.h"
namespace pyston { namespace pyston {
...@@ -1607,11 +1608,8 @@ static int fill_classic_mro(PyObject* mro, PyObject* cls) { ...@@ -1607,11 +1608,8 @@ static int fill_classic_mro(PyObject* mro, PyObject* cls) {
if (PyList_Append(mro, cls) < 0) if (PyList_Append(mro, cls) < 0)
return -1; return -1;
} }
Py_FatalError("unimplemented");
// We should add multiple inheritance for old-style classes bases = ((BoxedClassobj*)cls)->bases;
#if 0
bases = ((PyClassObject*)cls)->cl_bases;
assert(bases && PyTuple_Check(bases)); assert(bases && PyTuple_Check(bases));
n = PyTuple_GET_SIZE(bases); n = PyTuple_GET_SIZE(bases);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
...@@ -1620,7 +1618,6 @@ static int fill_classic_mro(PyObject* mro, PyObject* cls) { ...@@ -1620,7 +1618,6 @@ static int fill_classic_mro(PyObject* mro, PyObject* cls) {
return -1; return -1;
} }
return 0; return 0;
#endif
} }
static PyObject* classic_mro(PyObject* cls) { static PyObject* classic_mro(PyObject* cls) {
......
...@@ -144,10 +144,20 @@ public: ...@@ -144,10 +144,20 @@ public:
static Box* __get__(BoxedMethodDescriptor* self, Box* inst, Box* owner) { static Box* __get__(BoxedMethodDescriptor* self, Box* inst, Box* owner) {
RELEASE_ASSERT(self->cls == method_cls, ""); 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) if (inst == None)
return self; return self;
// CPython apparently returns a "builtin_function_or_method" object else
return boxInstanceMethod(inst, self); return boxInstanceMethod(inst, self);
} }
static Box* __call__(BoxedMethodDescriptor* self, Box* obj, BoxedTuple* varargs, Box** _args); 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 { ...@@ -451,10 +451,6 @@ extern "C" Py_ssize_t PySequence_Count(PyObject* o, PyObject* value) noexcept {
Py_FatalError("unimplemented"); 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 { extern "C" Py_ssize_t PySequence_Index(PyObject* o, PyObject* value) noexcept {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
......
...@@ -84,6 +84,15 @@ Box* classobjNew(Box* _cls, Box* _name, Box* _bases, Box** _args) { ...@@ -84,6 +84,15 @@ Box* classobjNew(Box* _cls, Box* _name, Box* _bases, Box** _args) {
raiseExcHelper(TypeError, "PyClass_New: bases must be a tuple"); raiseExcHelper(TypeError, "PyClass_New: bases must be a tuple");
BoxedTuple* bases = static_cast<BoxedTuple*>(_bases); 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); BoxedClassobj* made = new (cls) BoxedClassobj(name, bases);
made->giveAttr("__module__", boxString(getCurrentModule()->name())); made->giveAttr("__module__", boxString(getCurrentModule()->name()));
......
...@@ -1862,8 +1862,13 @@ extern "C" BoxedString* str(Box* obj) { ...@@ -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); obj = callattrInternal(obj, &str_str, CLASS_ONLY, NULL, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
} }
if (obj->cls != str_cls) { if (isSubclass(obj->cls, unicode_cls)) {
raiseExcHelper(TypeError, "__str__ did not return a string!"); 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); return static_cast<BoxedString*>(obj);
} }
...@@ -1874,8 +1879,13 @@ extern "C" BoxedString* repr(Box* 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); obj = callattrInternal(obj, &repr_str, CLASS_ONLY, NULL, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
if (obj->cls != str_cls) { if (isSubclass(obj->cls, unicode_cls)) {
raiseExcHelper(TypeError, "__repr__ did not return a string!"); 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); return static_cast<BoxedString*>(obj);
} }
...@@ -1939,8 +1949,8 @@ extern "C" BoxedInt* hash(Box* obj) { ...@@ -1939,8 +1949,8 @@ extern "C" BoxedInt* hash(Box* obj) {
Box* hash = getclsattr_internal(obj, "__hash__", NULL); Box* hash = getclsattr_internal(obj, "__hash__", NULL);
if (hash == NULL) { if (hash == NULL) {
ASSERT(isUserDefined(obj->cls) || obj->cls == function_cls || obj->cls == object_cls ASSERT(isUserDefined(obj->cls) || obj->cls == function_cls || obj->cls == object_cls || obj->cls == classobj_cls
|| obj->cls == classobj_cls, || obj->cls == module_cls,
"%s.__hash__", getTypeName(obj)); "%s.__hash__", getTypeName(obj));
// TODO not the best way to handle this... // TODO not the best way to handle this...
return static_cast<BoxedInt*>(boxInt((i64)obj)); return static_cast<BoxedInt*>(boxInt((i64)obj));
......
...@@ -1214,7 +1214,10 @@ extern "C" Box* strLen(BoxedString* self) { ...@@ -1214,7 +1214,10 @@ extern "C" Box* strLen(BoxedString* self) {
extern "C" Box* strStr(BoxedString* self) { extern "C" Box* strStr(BoxedString* self) {
assert(isSubclass(self->cls, str_cls)); 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] static bool _needs_escaping[256]
...@@ -1488,7 +1491,7 @@ extern "C" Box* strNew(BoxedClass* cls, Box* obj) { ...@@ -1488,7 +1491,7 @@ extern "C" Box* strNew(BoxedClass* cls, Box* obj) {
assert(isSubclass(cls, str_cls)); assert(isSubclass(cls, str_cls));
Box* rtn = str(obj); Box* rtn = str(obj);
assert(rtn->cls == str_cls); assert(isSubclass(rtn->cls, str_cls));
if (cls == str_cls) if (cls == str_cls)
return rtn; return rtn;
......
...@@ -1927,6 +1927,10 @@ void setupRuntime() { ...@@ -1927,6 +1927,10 @@ void setupRuntime() {
attrwrapper_cls->giveAttr("keys", new BoxedFunction(boxRTFunction((void*)AttrWrapper::keys, LIST, 1))); 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("values", new BoxedFunction(boxRTFunction((void*)AttrWrapper::values, LIST, 1)));
attrwrapper_cls->giveAttr("items", new BoxedFunction(boxRTFunction((void*)AttrWrapper::items, 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("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("__len__", new BoxedFunction(boxRTFunction((void*)AttrWrapper::len, BOXED_INT, 1)));
attrwrapper_cls->giveAttr("__iter__", new BoxedFunction(boxRTFunction((void*)AttrWrapper::iter, UNKNOWN, 1))); attrwrapper_cls->giveAttr("__iter__", new BoxedFunction(boxRTFunction((void*)AttrWrapper::iter, UNKNOWN, 1)));
......
...@@ -6,3 +6,8 @@ print repr(datetime.time()) ...@@ -6,3 +6,8 @@ print repr(datetime.time())
print datetime.datetime.__base__ print datetime.datetime.__base__
print repr(datetime.datetime(1, 2, 3)) print repr(datetime.datetime(1, 2, 3))
print str(datetime.timedelta(0)) 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(): class C():
pass pass
...@@ -166,3 +164,35 @@ try: ...@@ -166,3 +164,35 @@ try:
C.doesnt_exist C.doesnt_exist
except AttributeError as e: except AttributeError as e:
print 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') ...@@ -99,3 +99,41 @@ print "hello world".rsplit(u'l')
with open(u"/dev/null", u"r") as f: with open(u"/dev/null", u"r") as f:
print f.read() 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