Commit c5139df3 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #931 from kmod/coexist

Properly handle METH_COEXIST
parents e5bb2964 8e953dab
......@@ -2572,6 +2572,72 @@ extern "C" int PyType_IsSubtype(PyTypeObject* a, PyTypeObject* b) noexcept {
}
}
/* Initialize the __dict__ in a type object */
static int add_methods(PyTypeObject* type, PyMethodDef* meth) noexcept {
for (; meth->ml_name != NULL; meth++) {
auto name = internStringMortal(meth->ml_name);
PyObject* descr;
int err;
if (type->hasattr(name) && !(meth->ml_flags & METH_COEXIST))
continue;
if (meth->ml_flags & METH_CLASS) {
if (meth->ml_flags & METH_STATIC) {
PyErr_SetString(PyExc_ValueError, "method cannot be both class and static");
return -1;
}
// Pyston change: create these classmethods as normal methods, which will
// later just notice the METH_CLASS flag.
// descr = PyDescr_NewClassMethod(type, meth);
descr = PyDescr_NewMethod(type, meth);
} else if (meth->ml_flags & METH_STATIC) {
PyObject* cfunc = PyCFunction_New(meth, NULL);
if (cfunc == NULL)
return -1;
descr = PyStaticMethod_New(cfunc);
Py_DECREF(cfunc);
} else {
descr = PyDescr_NewMethod(type, meth);
}
if (descr == NULL)
return -1;
type->setattr(name, descr, NULL);
Py_DECREF(descr);
}
return 0;
}
static int add_members(PyTypeObject* type, PyMemberDef* memb) noexcept {
for (; memb->name != NULL; memb++) {
auto name = internStringMortal(memb->name);
PyObject* descr;
if (type->hasattr(name))
continue;
descr = PyDescr_NewMember(type, memb);
if (descr == NULL)
return -1;
type->setattr(name, descr, NULL);
Py_DECREF(descr);
}
return 0;
}
static int add_getset(PyTypeObject* type, PyGetSetDef* gsp) noexcept {
for (; gsp->name != NULL; gsp++) {
auto name = internStringMortal(gsp->name);
PyObject* descr;
if (type->hasattr(name))
continue;
descr = PyDescr_NewGetSet(type, gsp);
if (descr == NULL)
return -1;
type->setattr(name, descr, NULL);
Py_DECREF(descr);
}
return 0;
}
#define BUFFER_FLAGS (Py_TPFLAGS_HAVE_GETCHARBUFFER | Py_TPFLAGS_HAVE_NEWBUFFER)
// This is copied from CPython with some modifications:
......@@ -3313,19 +3379,17 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
abort();
}
for (PyMethodDef* method = cls->tp_methods; method && method->ml_name; ++method) {
cls->setattr(internStringMortal(method->ml_name), new BoxedMethodDescriptor(method, cls), NULL);
if (cls->tp_methods != NULL) {
if (add_methods(cls, cls->tp_methods) < 0)
return -1;
}
for (PyMemberDef* member = cls->tp_members; member && member->name; ++member) {
cls->giveAttr(internStringMortal(member->name), new BoxedMemberDescriptor(member));
if (cls->tp_members != NULL) {
if (add_members(cls, cls->tp_members) < 0)
return -1;
}
for (PyGetSetDef* getset = cls->tp_getset; getset && getset->name; ++getset) {
// TODO do something with __doc__
cls->giveAttr(internStringMortal(getset->name),
new (capi_getset_cls) BoxedGetsetDescriptor(getset->get, (void (*)(Box*, Box*, void*))getset->set,
getset->closure));
if (cls->tp_getset != NULL) {
if (add_getset(cls, cls->tp_getset) < 0)
return -1;
}
try {
......
......@@ -259,7 +259,7 @@ Box* BoxedMethodDescriptor::tppCall(Box* _self, CallRewriteArgs* rewrite_args, A
BoxedMethodDescriptor* self = static_cast<BoxedMethodDescriptor*>(_self);
int ml_flags = self->method->ml_flags;
int call_flags = ml_flags & (~METH_CLASS);
int call_flags = ml_flags & ~(METH_CLASS | METH_COEXIST | METH_STATIC);
if (rewrite_args && !rewrite_args->func_guarded) {
rewrite_args->obj->addAttrGuard(offsetof(BoxedMethodDescriptor, method), (intptr_t)self->method);
......@@ -423,8 +423,6 @@ Box* BoxedMethodDescriptor::descr_get(BoxedMethodDescriptor* self, Box* inst, Bo
if (self->method->ml_flags & METH_STATIC)
Py_FatalError("unimplemented");
if (self->method->ml_flags & METH_COEXIST)
Py_FatalError("unimplemented");
if (inst == NULL)
return self;
......@@ -677,6 +675,24 @@ extern "C" PyObject* PyStaticMethod_New(PyObject* callable) noexcept {
return new BoxedStaticmethod(callable);
}
extern "C" PyObject* PyDescr_NewMember(PyTypeObject* x, struct PyMemberDef* y) noexcept {
return new BoxedMemberDescriptor(y);
}
extern "C" PyObject* PyDescr_NewGetSet(PyTypeObject* x, struct PyGetSetDef* y) noexcept {
// TODO do something with __doc__
return new (capi_getset_cls) BoxedGetsetDescriptor(y->get, (void (*)(Box*, Box*, void*))y->set, y->closure);
}
extern "C" PyObject* PyDescr_NewClassMethod(PyTypeObject* x, PyMethodDef* y) noexcept {
Py_FatalError("unimplemented");
return NULL;
}
extern "C" PyObject* PyDescr_NewMethod(PyTypeObject* type, PyMethodDef* method) noexcept {
return new BoxedMethodDescriptor(method, type);
}
void setupDescr() {
member_descriptor_cls->giveAttr("__get__", new BoxedFunction(boxRTFunction((void*)memberGet, UNKNOWN, 3)));
member_descriptor_cls->freeze();
......
......@@ -20,20 +20,6 @@
#include "runtime/long.h"
#include "runtime/objmodel.h"
// Temp hack to get CType sort of importing
PyObject* PyDescr_NewMember(PyTypeObject* x, struct PyMemberDef* y) PYSTON_NOEXCEPT {
Py_FatalError("unimplemented");
return NULL;
}
PyObject* PyDescr_NewGetSet(PyTypeObject* x, struct PyGetSetDef* y) PYSTON_NOEXCEPT {
Py_FatalError("unimplemented");
return NULL;
}
PyObject* PyDescr_NewClassMethod(PyTypeObject* x, PyMethodDef* y) PYSTON_NOEXCEPT {
Py_FatalError("unimplemented");
return NULL;
}
namespace pyston {
void parseSlice(BoxedSlice* slice, int size, i64* out_start, i64* out_stop, i64* out_step, i64* out_length) {
......
......@@ -6,7 +6,7 @@ try:
print 1
print curses.version
print curses.longname()
curses.longname()
print curses.baudrate()
print curses.can_change_color()
curses.start_color()
......
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