Commit 39859d79 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge branch 'multiple_inheritance'

parents 53dc9612 fee6818c
...@@ -404,26 +404,26 @@ check: ...@@ -404,26 +404,26 @@ check:
@# jit_prof forces the use of GCC as the compiler, which can expose other errors, so just build it and see what happens: @# jit_prof forces the use of GCC as the compiler, which can expose other errors, so just build it and see what happens:
$(MAKE) pyston_prof $(MAKE) pyston_prof
@# and run some basic tests to make sure it works: @# and run some basic tests to make sure it works:
$(call checksha,./pyston_prof -cq $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d) $(call checksha,./pyston_prof -q $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d)
$(call checksha,./pyston_prof -cqn $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d) $(call checksha,./pyston_prof -qn $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d)
$(call checksha,./pyston_prof -cqO $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d) $(call checksha,./pyston_prof -qO $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d)
$(MAKE) check_release $(MAKE) check_release
echo "All tests passed" echo "All tests passed"
quick_check: quick_check:
$(MAKE) pyston_dbg $(MAKE) pyston_dbg
$(call checksha,./pyston_dbg -cq $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d) $(call checksha,./pyston_dbg -q $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d)
$(call checksha,./pyston_dbg -cqn $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d) $(call checksha,./pyston_dbg -qn $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d)
$(call checksha,./pyston_dbg -cqO $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d) $(call checksha,./pyston_dbg -qO $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d)
$(MAKE) pyston $(MAKE) pyston
$(call checksha,./pyston -cq $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d) $(call checksha,./pyston -q $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d)
$(call checksha,./pyston -cqn $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d) $(call checksha,./pyston -qn $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d)
$(call checksha,./pyston -cqO $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d) $(call checksha,./pyston -qO $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d)
$(MAKE) pyston_prof $(MAKE) pyston_prof
$(call checksha,./pyston_prof -cq $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d) $(call checksha,./pyston_prof -q $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d)
$(call checksha,./pyston_prof -cqn $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d) $(call checksha,./pyston_prof -qn $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d)
$(call checksha,./pyston_prof -cqO $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d) $(call checksha,./pyston_prof -qO $(TESTS_DIR)/raytrace_small.py,0544f4621dd45fe94205219488a2576b84dc044d)
Makefile.local: Makefile.local:
echo "Creating default Makefile.local" echo "Creating default Makefile.local"
......
...@@ -180,7 +180,13 @@ void RewriterVar::addAttrGuard(int offset, uint64_t val, bool negate) { ...@@ -180,7 +180,13 @@ void RewriterVar::addAttrGuard(int offset, uint64_t val, bool negate) {
} }
void Rewriter::_addAttrGuard(RewriterVar* var, int offset, uint64_t val, bool negate) { void Rewriter::_addAttrGuard(RewriterVar* var, int offset, uint64_t val, bool negate) {
assembler::Register var_reg = var->getInReg(); // TODO if var is a constant, we will end up emitting something like
// mov $0x123, %rax
// cmp $0x10(%rax), %rdi
// when we could just do
// cmp ($0x133), %rdi
assembler::Register var_reg = var->getInReg(Location::any(), /* allow_constant_in_reg */ true);
if (isLargeConstant(val)) { if (isLargeConstant(val)) {
assembler::Register reg = allocReg(Location::any(), /* otherThan */ var_reg); assembler::Register reg = allocReg(Location::any(), /* otherThan */ var_reg);
assert(reg != var_reg); assert(reg != var_reg);
...@@ -206,7 +212,12 @@ RewriterVar* RewriterVar::getAttr(int offset, Location dest, assembler::MovType ...@@ -206,7 +212,12 @@ RewriterVar* RewriterVar::getAttr(int offset, Location dest, assembler::MovType
} }
void Rewriter::_getAttr(RewriterVar* result, RewriterVar* ptr, int offset, Location dest, assembler::MovType type) { void Rewriter::_getAttr(RewriterVar* result, RewriterVar* ptr, int offset, Location dest, assembler::MovType type) {
assembler::Register ptr_reg = ptr->getInReg(); // TODO if var is a constant, we will end up emitting something like
// mov $0x123, %rax
// mov $0x10(%rax), %rdi
// when we could just do
// mov ($0x133), %rdi
assembler::Register ptr_reg = ptr->getInReg(Location::any(), /* allow_constant_in_reg */ true);
// It's okay to bump the use now, since it's fine to allocate the result // It's okay to bump the use now, since it's fine to allocate the result
// in the same register as ptr // in the same register as ptr
......
...@@ -293,15 +293,16 @@ extern "C" PyObject* PyObject_CallFunctionObjArgs(PyObject* callable, ...) noexc ...@@ -293,15 +293,16 @@ extern "C" PyObject* PyObject_CallFunctionObjArgs(PyObject* callable, ...) noexc
} }
extern "C" PyObject* PyObject_CallObject(PyObject* obj, PyObject* args) noexcept { extern "C" PyObject* PyObject_CallObject(PyObject* obj, PyObject* args) noexcept {
RELEASE_ASSERT(args, ""); // actually it looks like this is allowed to be NULL
RELEASE_ASSERT(args->cls == tuple_cls, "");
// TODO do something like this? not sure if this is safe; will people expect that calling into a known function // TODO do something like this? not sure if this is safe; will people expect that calling into a known function
// won't end up doing a GIL check? // won't end up doing a GIL check?
// threading::GLDemoteRegion _gil_demote; // threading::GLDemoteRegion _gil_demote;
try { try {
Box* r = runtimeCall(obj, ArgPassSpec(0, 0, true, false), args, NULL, NULL, NULL, NULL); Box* r;
if (args)
r = runtimeCall(obj, ArgPassSpec(0, 0, true, false), args, NULL, NULL, NULL, NULL);
else
r = runtimeCall(obj, ArgPassSpec(0, 0, false, false), NULL, NULL, NULL, NULL, NULL);
return r; return r;
} catch (ExcInfo e) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
......
...@@ -82,7 +82,7 @@ static int _ustrlen(Py_UNICODE* u) { ...@@ -82,7 +82,7 @@ static int _ustrlen(Py_UNICODE* u) {
#endif #endif
static PyObject* do_mktuple(const char**, va_list*, int, int, int) noexcept; static PyObject* do_mktuple(const char**, va_list*, int, int, int) noexcept;
// static PyObject *do_mklist(const char**, va_list *, int, int, int) noexcept; static PyObject* do_mklist(const char**, va_list*, int, int, int) noexcept;
// static PyObject *do_mkdict(const char**, va_list *, int, int, int) noexcept; // static PyObject *do_mkdict(const char**, va_list *, int, int, int) noexcept;
static PyObject* do_mkvalue(const char**, va_list*, int) noexcept; static PyObject* do_mkvalue(const char**, va_list*, int) noexcept;
...@@ -92,10 +92,10 @@ static PyObject* do_mkvalue(const char** p_format, va_list* p_va, int flags) noe ...@@ -92,10 +92,10 @@ static PyObject* do_mkvalue(const char** p_format, va_list* p_va, int flags) noe
case '(': case '(':
return do_mktuple(p_format, p_va, ')', countformat(*p_format, ')'), flags); return do_mktuple(p_format, p_va, ')', countformat(*p_format, ')'), flags);
#if 0
case '[': case '[':
return do_mklist(p_format, p_va, ']', countformat(*p_format, ']'), flags); return do_mklist(p_format, p_va, ']', countformat(*p_format, ']'), flags);
#if 0
case '{': case '{':
return do_mkdict(p_format, p_va, '}', countformat(*p_format, '}'), flags); return do_mkdict(p_format, p_va, '}', countformat(*p_format, '}'), flags);
#endif #endif
...@@ -239,6 +239,43 @@ static PyObject* do_mktuple(const char** p_format, va_list* p_va, int endchar, i ...@@ -239,6 +239,43 @@ static PyObject* do_mktuple(const char** p_format, va_list* p_va, int endchar, i
return v; return v;
} }
static PyObject* do_mklist(const char** p_format, va_list* p_va, int endchar, int n, int flags) noexcept {
PyObject* v;
int i;
int itemfailed = 0;
if (n < 0)
return NULL;
v = PyList_New(n);
if (v == NULL)
return NULL;
/* Note that we can't bail immediately on error as this will leak
refcounts on any 'N' arguments. */
for (i = 0; i < n; i++) {
PyObject* w = do_mkvalue(p_format, p_va, flags);
if (w == NULL) {
itemfailed = 1;
Py_INCREF(Py_None);
w = Py_None;
}
PyList_SET_ITEM(v, i, w);
}
if (itemfailed) {
/* do_mkvalue() should have already set an error */
Py_DECREF(v);
return NULL;
}
if (**p_format != endchar) {
Py_DECREF(v);
PyErr_SetString(PyExc_SystemError, "Unmatched paren in format");
return NULL;
}
if (endchar)
++*p_format;
return v;
}
static PyObject* va_build_value(const char* fmt, va_list va, int flags) noexcept { static PyObject* va_build_value(const char* fmt, va_list va, int flags) noexcept {
int n = countformat(fmt, '\0'); int n = countformat(fmt, '\0');
......
This diff is collapsed.
...@@ -23,7 +23,14 @@ namespace pyston { ...@@ -23,7 +23,14 @@ namespace pyston {
bool update_slot(BoxedClass* self, const std::string& attr) noexcept; bool update_slot(BoxedClass* self, const std::string& attr) noexcept;
void fixup_slot_dispatchers(BoxedClass* self) noexcept; void fixup_slot_dispatchers(BoxedClass* self) noexcept;
void PystonType_Ready(BoxedClass* cls); void commonClassSetup(BoxedClass* cls);
// We need to expose these due to our different file organization (they
// are defined as part of the CPython copied into typeobject.c, but used
// from Pyston code).
// We could probably unify things more but that's for later.
PyTypeObject* best_base(PyObject* bases) noexcept;
PyObject* mro_external(PyObject* self) noexcept;
} }
#endif #endif
...@@ -630,8 +630,8 @@ LargeArena::LargeFreeChunk* LargeArena::get_from_size_list(LargeFreeChunk** list ...@@ -630,8 +630,8 @@ LargeArena::LargeFreeChunk* LargeArena::get_from_size_list(LargeFreeChunk** list
section->free_chunk_map[i] = 0; section->free_chunk_map[i] = 0;
} }
assert(section->num_free_chunks >= size >> CHUNK_BITS);
section->num_free_chunks -= size >> CHUNK_BITS; section->num_free_chunks -= size >> CHUNK_BITS;
assert(section->num_free_chunks >= 0);
return free_chunks; return free_chunks;
} }
......
...@@ -730,7 +730,7 @@ static BoxedClass* makeBuiltinException(BoxedClass* base, const char* name, int ...@@ -730,7 +730,7 @@ static BoxedClass* makeBuiltinException(BoxedClass* base, const char* name, int
if (size == 0) if (size == 0)
size = base->tp_basicsize; size = base->tp_basicsize;
BoxedClass* cls = new BoxedHeapClass(base, NULL, offsetof(BoxedException, attrs), size, false, name); BoxedClass* cls = BoxedHeapClass::create(type_cls, base, NULL, offsetof(BoxedException, attrs), size, false, name);
cls->giveAttr("__module__", boxStrConstant("exceptions")); cls->giveAttr("__module__", boxStrConstant("exceptions"));
if (base == object_cls) { if (base == object_cls) {
...@@ -954,7 +954,8 @@ Box* pydumpAddr(Box* p) { ...@@ -954,7 +954,8 @@ Box* pydumpAddr(Box* p) {
void setupBuiltins() { void setupBuiltins() {
builtins_module = createModule("__builtin__", "__builtin__"); builtins_module = createModule("__builtin__", "__builtin__");
BoxedHeapClass* ellipsis_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(Box), false, "ellipsis"); BoxedHeapClass* ellipsis_cls
= BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(Box), false, "ellipsis");
Box* Ellipsis = new (ellipsis_cls) Box(); Box* Ellipsis = new (ellipsis_cls) Box();
assert(Ellipsis->cls); assert(Ellipsis->cls);
gc::registerPermanentRoot(Ellipsis); gc::registerPermanentRoot(Ellipsis);
...@@ -967,7 +968,8 @@ void setupBuiltins() { ...@@ -967,7 +968,8 @@ void setupBuiltins() {
builtins_module->giveAttr( builtins_module->giveAttr(
"print", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)print, NONE, 0, 0, true, true), "print")); "print", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)print, NONE, 0, 0, true, true), "print"));
notimplemented_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(Box), false, "NotImplementedType"); notimplemented_cls
= BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(Box), false, "NotImplementedType");
notimplemented_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)notimplementedRepr, STR, 1))); notimplemented_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)notimplementedRepr, STR, 1)));
notimplemented_cls->freeze(); notimplemented_cls->freeze();
NotImplemented = new (notimplemented_cls) Box(); NotImplemented = new (notimplemented_cls) Box();
...@@ -1046,8 +1048,8 @@ void setupBuiltins() { ...@@ -1046,8 +1048,8 @@ void setupBuiltins() {
builtins_module->giveAttr("__import__", new BoxedBuiltinFunctionOrMethod(import_func, "__import__", builtins_module->giveAttr("__import__", new BoxedBuiltinFunctionOrMethod(import_func, "__import__",
{ None, None, None, new BoxedInt(-1) })); { None, None, None, new BoxedInt(-1) }));
enumerate_cls enumerate_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedEnumerate::gcHandler, 0, sizeof(BoxedEnumerate),
= new BoxedHeapClass(object_cls, &BoxedEnumerate::gcHandler, 0, sizeof(BoxedEnumerate), false, "enumerate"); false, "enumerate");
enumerate_cls->giveAttr( enumerate_cls->giveAttr(
"__new__", "__new__",
new BoxedFunction(boxRTFunction((void*)BoxedEnumerate::new_, UNKNOWN, 3, 1, false, false), { boxInt(0) })); new BoxedFunction(boxRTFunction((void*)BoxedEnumerate::new_, UNKNOWN, 3, 1, false, false), { boxInt(0) }));
......
...@@ -294,7 +294,8 @@ void setupSys() { ...@@ -294,7 +294,8 @@ void setupSys() {
sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX)); sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX));
sys_flags_cls = new BoxedHeapClass(object_cls, BoxedSysFlags::gcHandler, 0, sizeof(BoxedSysFlags), false, "flags"); sys_flags_cls = BoxedHeapClass::create(type_cls, object_cls, BoxedSysFlags::gcHandler, 0, sizeof(BoxedSysFlags),
false, "flags");
sys_flags_cls->giveAttr("__new__", sys_flags_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)BoxedSysFlags::__new__, UNKNOWN, 1, 0, true, true))); new BoxedFunction(boxRTFunction((void*)BoxedSysFlags::__new__, UNKNOWN, 1, 0, true, true)));
#define ADD(name) \ #define ADD(name) \
......
...@@ -179,7 +179,7 @@ void setupThread() { ...@@ -179,7 +179,7 @@ void setupThread() {
thread_module->giveAttr( thread_module->giveAttr(
"stack_size", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)stackSize, BOXED_INT, 0), "stack_size")); "stack_size", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)stackSize, BOXED_INT, 0), "stack_size"));
thread_lock_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedThreadLock), false, "lock"); thread_lock_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedThreadLock), false, "lock");
thread_lock_cls->giveAttr("__module__", boxStrConstant("thread")); thread_lock_cls->giveAttr("__module__", boxStrConstant("thread"));
thread_lock_cls->giveAttr( thread_lock_cls->giveAttr(
"acquire", new BoxedFunction(boxRTFunction((void*)BoxedThreadLock::acquire, BOXED_BOOL, 2, 1, false, false), "acquire", new BoxedFunction(boxRTFunction((void*)BoxedThreadLock::acquire, BOXED_BOOL, 2, 1, false, false),
...@@ -191,13 +191,13 @@ void setupThread() { ...@@ -191,13 +191,13 @@ void setupThread() {
thread_lock_cls->giveAttr("__exit__", new BoxedFunction(boxRTFunction((void*)BoxedThreadLock::exit, NONE, 4))); thread_lock_cls->giveAttr("__exit__", new BoxedFunction(boxRTFunction((void*)BoxedThreadLock::exit, NONE, 4)));
thread_lock_cls->freeze(); thread_lock_cls->freeze();
thread_local_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedThreadLocal), false, "_local"); thread_local_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedThreadLocal), false, "_local");
thread_local_cls->giveAttr("__module__", boxStrConstant("thread")); thread_local_cls->giveAttr("__module__", boxStrConstant("thread"));
thread_local_cls->freeze(); thread_local_cls->freeze();
thread_module->giveAttr("_local", thread_local_cls); thread_module->giveAttr("_local", thread_local_cls);
BoxedClass* ThreadError BoxedClass* ThreadError = BoxedHeapClass::create(type_cls, Exception, NULL, Exception->attrs_offset,
= new BoxedHeapClass(Exception, NULL, Exception->attrs_offset, Exception->tp_basicsize, false, "error"); Exception->tp_basicsize, false, "error");
ThreadError->giveAttr("__module__", boxStrConstant("thread")); ThreadError->giveAttr("__module__", boxStrConstant("thread"));
ThreadError->freeze(); ThreadError->freeze();
......
...@@ -501,6 +501,8 @@ extern "C" Py_ssize_t PySequence_Index(PyObject* o, PyObject* value) noexcept { ...@@ -501,6 +501,8 @@ extern "C" Py_ssize_t PySequence_Index(PyObject* o, PyObject* value) noexcept {
extern "C" PyObject* PySequence_Tuple(PyObject* o) noexcept { extern "C" PyObject* PySequence_Tuple(PyObject* o) noexcept {
if (o->cls == tuple_cls) if (o->cls == tuple_cls)
return o; return o;
if (PyList_Check(o))
return PyList_AsTuple(o);
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
...@@ -1543,7 +1545,7 @@ static Box* methodGetDoc(Box* b, void*) { ...@@ -1543,7 +1545,7 @@ static Box* methodGetDoc(Box* b, void*) {
} }
void setupCAPI() { void setupCAPI() {
capifunc_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedCApiFunction), false, "capifunc"); capifunc_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedCApiFunction), false, "capifunc");
capifunc_cls->giveAttr("__repr__", capifunc_cls->giveAttr("__repr__",
new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__repr__, UNKNOWN, 1))); new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__repr__, UNKNOWN, 1)));
...@@ -1554,7 +1556,7 @@ void setupCAPI() { ...@@ -1554,7 +1556,7 @@ void setupCAPI() {
capifunc_cls->freeze(); capifunc_cls->freeze();
method_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedMethodDescriptor), false, "method"); method_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedMethodDescriptor), false, "method");
method_cls->giveAttr("__get__", method_cls->giveAttr("__get__",
new BoxedFunction(boxRTFunction((void*)BoxedMethodDescriptor::__get__, UNKNOWN, 3))); new BoxedFunction(boxRTFunction((void*)BoxedMethodDescriptor::__get__, UNKNOWN, 3)));
method_cls->giveAttr("__call__", new BoxedFunction(boxRTFunction((void*)BoxedMethodDescriptor::__call__, UNKNOWN, 2, method_cls->giveAttr("__call__", new BoxedFunction(boxRTFunction((void*)BoxedMethodDescriptor::__call__, UNKNOWN, 2,
...@@ -1562,13 +1564,14 @@ void setupCAPI() { ...@@ -1562,13 +1564,14 @@ void setupCAPI() {
method_cls->giveAttr("__doc__", new (pyston_getset_cls) BoxedGetsetDescriptor(methodGetDoc, NULL, NULL)); method_cls->giveAttr("__doc__", new (pyston_getset_cls) BoxedGetsetDescriptor(methodGetDoc, NULL, NULL));
method_cls->freeze(); method_cls->freeze();
wrapperdescr_cls wrapperdescr_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedWrapperDescriptor), false,
= new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedWrapperDescriptor), false, "wrapper_descriptor"); "wrapper_descriptor");
wrapperdescr_cls->giveAttr("__get__", wrapperdescr_cls->giveAttr("__get__",
new BoxedFunction(boxRTFunction((void*)BoxedWrapperDescriptor::__get__, UNKNOWN, 3))); new BoxedFunction(boxRTFunction((void*)BoxedWrapperDescriptor::__get__, UNKNOWN, 3)));
wrapperdescr_cls->freeze(); wrapperdescr_cls->freeze();
wrapperobject_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedWrapperObject), false, "method-wrapper"); wrapperobject_cls
= BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedWrapperObject), false, "method-wrapper");
wrapperobject_cls->giveAttr( wrapperobject_cls->giveAttr(
"__call__", new BoxedFunction(boxRTFunction((void*)BoxedWrapperObject::__call__, UNKNOWN, 1, 0, true, true))); "__call__", new BoxedFunction(boxRTFunction((void*)BoxedWrapperObject::__call__, UNKNOWN, 1, 0, true, true)));
wrapperobject_cls->freeze(); wrapperobject_cls->freeze();
......
...@@ -270,10 +270,10 @@ Box* instanceSetitem(Box* _inst, Box* key, Box* value) { ...@@ -270,10 +270,10 @@ Box* instanceSetitem(Box* _inst, Box* key, Box* value) {
} }
void setupClassobj() { void setupClassobj() {
classobj_cls = new BoxedHeapClass(object_cls, &BoxedClassobj::gcHandler, offsetof(BoxedClassobj, attrs), classobj_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedClassobj::gcHandler,
sizeof(BoxedClassobj), false, "classobj"); offsetof(BoxedClassobj, attrs), sizeof(BoxedClassobj), false, "classobj");
instance_cls = new BoxedHeapClass(object_cls, &BoxedInstance::gcHandler, offsetof(BoxedInstance, attrs), instance_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedInstance::gcHandler,
sizeof(BoxedInstance), false, "instance"); offsetof(BoxedInstance, attrs), sizeof(BoxedInstance), false, "instance");
classobj_cls->giveAttr("__new__", classobj_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)classobjNew, UNKNOWN, 4, 0, false, false))); new BoxedFunction(boxRTFunction((void*)classobjNew, UNKNOWN, 4, 0, false, false)));
......
...@@ -572,13 +572,15 @@ static Box* dict_repr(PyObject* self) noexcept { ...@@ -572,13 +572,15 @@ static Box* dict_repr(PyObject* self) noexcept {
} }
void setupDict() { void setupDict() {
dict_iterator_cls = new BoxedHeapClass(object_cls, &dictIteratorGCHandler, 0, sizeof(BoxedDict), false, dict_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &dictIteratorGCHandler, 0, sizeof(BoxedDict),
"dictionary-itemiterator"); false, "dictionary-itemiterator");
dict_keys_cls = new BoxedHeapClass(object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false, "dict_keys"); dict_keys_cls = BoxedHeapClass::create(type_cls, object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false,
dict_values_cls "dict_keys");
= new BoxedHeapClass(object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false, "dict_values"); dict_values_cls = BoxedHeapClass::create(type_cls, object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false,
dict_items_cls = new BoxedHeapClass(object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false, "dict_items"); "dict_values");
dict_items_cls = BoxedHeapClass::create(type_cls, object_cls, &dictViewGCHandler, 0, sizeof(BoxedDictView), false,
"dict_items");
dict_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)dictLen, BOXED_INT, 1))); dict_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)dictLen, BOXED_INT, 1)));
dict_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)dictNew, UNKNOWN, 1, 0, true, true))); dict_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)dictNew, UNKNOWN, 1, 0, true, true)));
......
...@@ -298,7 +298,7 @@ void generatorDestructor(Box* b) { ...@@ -298,7 +298,7 @@ void generatorDestructor(Box* b) {
} }
void setupGenerator() { void setupGenerator() {
generator_cls = new BoxedHeapClass(object_cls, &generatorGCHandler, offsetof(BoxedGenerator, attrs), generator_cls = BoxedHeapClass::create(type_cls, object_cls, &generatorGCHandler, offsetof(BoxedGenerator, attrs),
sizeof(BoxedGenerator), false, "generator"); sizeof(BoxedGenerator), false, "generator");
generator_cls->simple_destructor = generatorDestructor; generator_cls->simple_destructor = generatorDestructor;
generator_cls->giveAttr("__iter__", generator_cls->giveAttr("__iter__",
......
...@@ -178,8 +178,8 @@ Box* xrangeReversed(Box* self) { ...@@ -178,8 +178,8 @@ Box* xrangeReversed(Box* self) {
} }
void setupXrange() { void setupXrange() {
xrange_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedXrange), false, "xrange"); xrange_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedXrange), false, "xrange");
xrange_iterator_cls = new BoxedHeapClass(object_cls, &BoxedXrangeIterator::xrangeIteratorGCHandler, 0, xrange_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &BoxedXrangeIterator::xrangeIteratorGCHandler, 0,
sizeof(BoxedXrangeIterator), false, "rangeiterator"); sizeof(BoxedXrangeIterator), false, "rangeiterator");
xrange_cls->giveAttr( xrange_cls->giveAttr(
......
...@@ -141,7 +141,8 @@ extern "C" PyObject* PySeqIter_New(PyObject* seq) noexcept { ...@@ -141,7 +141,8 @@ extern "C" PyObject* PySeqIter_New(PyObject* seq) noexcept {
} }
void setupIter() { void setupIter() {
seqiter_cls = new BoxedHeapClass(object_cls, seqiterGCVisit, 0, sizeof(BoxedSeqIter), false, "iterator"); seqiter_cls
= BoxedHeapClass::create(type_cls, object_cls, seqiterGCVisit, 0, sizeof(BoxedSeqIter), false, "iterator");
seqiter_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)seqiterNext, UNKNOWN, 1))); seqiter_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)seqiterNext, UNKNOWN, 1)));
seqiter_cls->giveAttr("__hasnext__", new BoxedFunction(boxRTFunction((void*)seqiterHasnext, BOXED_BOOL, 1))); seqiter_cls->giveAttr("__hasnext__", new BoxedFunction(boxRTFunction((void*)seqiterHasnext, BOXED_BOOL, 1)));
...@@ -149,7 +150,7 @@ void setupIter() { ...@@ -149,7 +150,7 @@ void setupIter() {
seqiter_cls->freeze(); seqiter_cls->freeze();
seqreviter_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedSeqIter), false, "reversed"); seqreviter_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, sizeof(BoxedSeqIter), false, "reversed");
seqreviter_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)seqiterNext, UNKNOWN, 1))); seqreviter_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)seqiterNext, UNKNOWN, 1)));
seqreviter_cls->giveAttr("__hasnext__", new BoxedFunction(boxRTFunction((void*)seqreviterHasnext, BOXED_BOOL, 1))); seqreviter_cls->giveAttr("__hasnext__", new BoxedFunction(boxRTFunction((void*)seqreviterHasnext, BOXED_BOOL, 1)));
...@@ -157,8 +158,8 @@ void setupIter() { ...@@ -157,8 +158,8 @@ void setupIter() {
seqreviter_cls->freeze(); seqreviter_cls->freeze();
iterwrapper_cls iterwrapper_cls = BoxedHeapClass::create(type_cls, object_cls, iterwrapperGCVisit, 0, sizeof(BoxedIterWrapper),
= new BoxedHeapClass(object_cls, iterwrapperGCVisit, 0, sizeof(BoxedIterWrapper), false, "iterwrapper"); false, "iterwrapper");
iterwrapper_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)iterwrapperNext, UNKNOWN, 1))); iterwrapper_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)iterwrapperNext, UNKNOWN, 1)));
iterwrapper_cls->giveAttr("__hasnext__", iterwrapper_cls->giveAttr("__hasnext__",
......
...@@ -49,6 +49,19 @@ extern "C" PyObject** PyList_Items(PyObject* op) noexcept { ...@@ -49,6 +49,19 @@ extern "C" PyObject** PyList_Items(PyObject* op) noexcept {
return &static_cast<BoxedList*>(op)->elts->elts[0]; return &static_cast<BoxedList*>(op)->elts->elts[0];
} }
extern "C" PyObject* PyList_AsTuple(PyObject* v) noexcept {
PyObject* w;
PyObject** p, **q;
Py_ssize_t n;
if (v == NULL || !PyList_Check(v)) {
PyErr_BadInternalCall();
return NULL;
}
auto l = static_cast<BoxedList*>(v);
return new BoxedTuple(BoxedTuple::GCVector(l->elts->elts, l->elts->elts + l->size));
}
extern "C" Box* listRepr(BoxedList* self) { extern "C" Box* listRepr(BoxedList* self) {
LOCK_REGION(self->lock.asRead()); LOCK_REGION(self->lock.asRead());
...@@ -751,10 +764,10 @@ extern "C" int PyList_SetSlice(PyObject* a, Py_ssize_t ilow, Py_ssize_t ihigh, P ...@@ -751,10 +764,10 @@ extern "C" int PyList_SetSlice(PyObject* a, Py_ssize_t ilow, Py_ssize_t ihigh, P
} }
void setupList() { void setupList() {
list_iterator_cls list_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &listIteratorGCHandler, 0, sizeof(BoxedList),
= new BoxedHeapClass(object_cls, &listIteratorGCHandler, 0, sizeof(BoxedList), false, "listiterator"); false, "listiterator");
list_reverse_iterator_cls = new BoxedHeapClass(object_cls, &listIteratorGCHandler, 0, sizeof(BoxedListIterator), list_reverse_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &listIteratorGCHandler, 0,
false, "listreverseiterator"); sizeof(BoxedListIterator), false, "listreverseiterator");
list_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)listLen, BOXED_INT, 1))); list_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)listLen, BOXED_INT, 1)));
......
This diff is collapsed.
...@@ -246,7 +246,8 @@ Box* setNonzero(BoxedSet* self) { ...@@ -246,7 +246,8 @@ Box* setNonzero(BoxedSet* self) {
using namespace pyston::set; using namespace pyston::set;
void setupSet() { void setupSet() {
set_iterator_cls = new BoxedHeapClass(object_cls, &setIteratorGCHandler, 0, sizeof(BoxedSet), false, "setiterator"); set_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &setIteratorGCHandler, 0, sizeof(BoxedSet), false,
"setiterator");
set_iterator_cls->giveAttr("__hasnext__", set_iterator_cls->giveAttr("__hasnext__",
new BoxedFunction(boxRTFunction((void*)setiteratorHasnext, BOXED_BOOL, 1))); new BoxedFunction(boxRTFunction((void*)setiteratorHasnext, BOXED_BOOL, 1)));
set_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)setiteratorNext, UNKNOWN, 1))); set_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)setiteratorNext, UNKNOWN, 1)));
......
...@@ -2208,8 +2208,8 @@ void setupStr() { ...@@ -2208,8 +2208,8 @@ void setupStr() {
str_cls->simple_destructor = strDestructor; str_cls->simple_destructor = strDestructor;
str_cls->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER; str_cls->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
str_iterator_cls str_iterator_cls = BoxedHeapClass::create(type_cls, object_cls, &strIteratorGCHandler, 0,
= new BoxedHeapClass(object_cls, &strIteratorGCHandler, 0, sizeof(BoxedStringIterator), false, "striterator"); sizeof(BoxedStringIterator), false, "striterator");
str_iterator_cls->giveAttr("__hasnext__", str_iterator_cls->giveAttr("__hasnext__",
new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::hasnext, BOXED_BOOL, 1))); new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::hasnext, BOXED_BOOL, 1)));
str_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::next, STR, 1))); str_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::next, STR, 1)));
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <sstream> #include <sstream>
#include "capi/types.h"
#include "core/types.h" #include "core/types.h"
#include "gc/collector.h" #include "gc/collector.h"
#include "runtime/objmodel.h" #include "runtime/objmodel.h"
...@@ -66,15 +67,68 @@ Box* superGetattribute(Box* _s, Box* _attr) { ...@@ -66,15 +67,68 @@ Box* superGetattribute(Box* _s, Box* _attr) {
} }
if (!skip) { if (!skip) {
// We don't support multiple inheritance yet, so the lookup order is simple: PyObject* mro, *res, *tmp, *dict;
Box* r = typeLookup(s->type->tp_base, attr->s, NULL); PyTypeObject* starttype;
descrgetfunc f;
if (r) { Py_ssize_t i, n;
return processDescriptor(r, (s->obj == s->obj_type ? None : s->obj), s->obj_type);
starttype = s->obj_type;
mro = starttype->tp_mro;
if (mro == NULL)
n = 0;
else {
assert(PyTuple_Check(mro));
n = PyTuple_GET_SIZE(mro);
}
for (i = 0; i < n; i++) {
if ((PyObject*)(s->type) == PyTuple_GET_ITEM(mro, i))
break;
}
i++;
res = NULL;
for (; i < n; i++) {
tmp = PyTuple_GET_ITEM(mro, i);
// Pyston change:
#if 0
if (PyType_Check(tmp))
dict = ((PyTypeObject *)tmp)->tp_dict;
else if (PyClass_Check(tmp))
dict = ((PyClassObject *)tmp)->cl_dict;
else
continue;
res = PyDict_GetItem(dict, name);
#endif
res = tmp->getattr(attr->s);
if (res != NULL) {
// Pyston change:
#if 0
Py_INCREF(res);
f = Py_TYPE(res)->tp_descr_get;
if (f != NULL) {
tmp = f(res,
/* Only pass 'obj' param if
this is instance-mode sper
(See SF ID #743627)
*/
(s->obj == (PyObject *)
s->obj_type
? (PyObject *)NULL
: s->obj),
(PyObject *)starttype);
Py_DECREF(res);
res = tmp;
}
#endif
return processDescriptor(res, (s->obj == s->obj_type ? None : s->obj), s->obj_type);
}
} }
} }
Box* r = typeLookup(s->cls, attr->s, NULL); Box* r = typeLookup(s->cls, attr->s, NULL);
// TODO implement this
RELEASE_ASSERT(r, "should call the equivalent of objectGetattr here"); RELEASE_ASSERT(r, "should call the equivalent of objectGetattr here");
return processDescriptor(r, s, s->cls); return processDescriptor(r, s, s->cls);
} }
...@@ -132,7 +186,8 @@ Box* superInit(Box* _self, Box* _type, Box* obj) { ...@@ -132,7 +186,8 @@ Box* superInit(Box* _self, Box* _type, Box* obj) {
} }
void setupSuper() { void setupSuper() {
super_cls = new BoxedHeapClass(object_cls, &BoxedSuper::gcHandler, 0, sizeof(BoxedSuper), false, "super"); super_cls
= BoxedHeapClass::create(type_cls, object_cls, &BoxedSuper::gcHandler, 0, sizeof(BoxedSuper), false, "super");
super_cls->giveAttr("__getattribute__", new BoxedFunction(boxRTFunction((void*)superGetattribute, UNKNOWN, 2))); super_cls->giveAttr("__getattribute__", new BoxedFunction(boxRTFunction((void*)superGetattribute, UNKNOWN, 2)));
super_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)superRepr, STR, 1))); super_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)superRepr, STR, 1)));
......
...@@ -107,8 +107,8 @@ Box* BoxedTraceback::getLines(Box* b) { ...@@ -107,8 +107,8 @@ Box* BoxedTraceback::getLines(Box* b) {
} }
void setupTraceback() { void setupTraceback() {
traceback_cls traceback_cls = BoxedHeapClass::create(type_cls, object_cls, BoxedTraceback::gcHandler, 0, sizeof(BoxedTraceback),
= new BoxedHeapClass(object_cls, BoxedTraceback::gcHandler, 0, sizeof(BoxedTraceback), false, "traceback"); false, "traceback");
traceback_cls->giveAttr("getLines", new BoxedFunction(boxRTFunction((void*)BoxedTraceback::getLines, UNKNOWN, 1))); traceback_cls->giveAttr("getLines", new BoxedFunction(boxRTFunction((void*)BoxedTraceback::getLines, UNKNOWN, 1)));
......
...@@ -386,7 +386,8 @@ extern "C" void tupleIteratorGCHandler(GCVisitor* v, Box* b) { ...@@ -386,7 +386,8 @@ extern "C" void tupleIteratorGCHandler(GCVisitor* v, Box* b) {
void setupTuple() { void setupTuple() {
tuple_iterator_cls = new BoxedHeapClass(object_cls, &tupleIteratorGCHandler, 0, sizeof(BoxedTuple), false, "tuple"); tuple_iterator_cls
= BoxedHeapClass::create(type_cls, object_cls, &tupleIteratorGCHandler, 0, sizeof(BoxedTuple), false, "tuple");
tuple_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)tupleNew, UNKNOWN, 1, 0, true, true))); tuple_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)tupleNew, UNKNOWN, 1, 0, true, true)));
CLFunction* getitem = createRTFunction(2, 0, 0, 0); CLFunction* getitem = createRTFunction(2, 0, 0, 0);
......
This diff is collapsed.
...@@ -192,9 +192,15 @@ public: ...@@ -192,9 +192,15 @@ public:
void freeze(); void freeze();
protected:
// These functions are not meant for external callers and will mostly just be called
// by BoxedHeapClass::create(), but setupRuntime() also needs to do some manual class
// creation due to bootstrapping issues.
void finishInitialization();
BoxedClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size, bool is_user_defined); BoxedClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size, bool is_user_defined);
DEFAULT_CLASS(type_cls); friend void setupRuntime();
}; };
class BoxedHeapClass : public BoxedClass { class BoxedHeapClass : public BoxedClass {
...@@ -207,15 +213,22 @@ public: ...@@ -207,15 +213,22 @@ public:
BoxedString* ht_name; BoxedString* ht_name;
PyObject** ht_slots; PyObject** ht_slots;
BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size, bool is_user_defined, // These functions are the preferred way to construct new types:
const std::string& name); static BoxedHeapClass* create(BoxedClass* metatype, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset,
int instance_size, bool is_user_defined, BoxedString* name, BoxedTuple* bases);
static BoxedHeapClass* create(BoxedClass* metatype, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset,
int instance_size, bool is_user_defined, const std::string& name);
private:
// These functions are not meant for external callers and will mostly just be called
// by BoxedHeapClass::create(), but setupRuntime() also needs to do some manual class
// creation due to bootstrapping issues.
BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size, bool is_user_defined, BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size, bool is_user_defined,
BoxedString* name); BoxedString* name);
// This constructor is only used for bootstrapping purposes to be called for types that friend void setupRuntime();
// are initialized before str_cls.
BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, int instance_size, bool is_user_defined); DEFAULT_CLASS(type_cls);
}; };
static_assert(sizeof(pyston::Box) == sizeof(struct _object), ""); static_assert(sizeof(pyston::Box) == sizeof(struct _object), "");
......
# Testing the basic multiple-inheritance rules and functionality:
class C(object):
n = 1
def c(self):
print "C.c()"
def f(self):
print "C.f()", self.n
class D(object):
n = 2
def d(self):
print "D.d()"
def f(self):
print "D.f()", self.n
class E(C, D):
pass
class F(D, C):
pass
class G(E, D):
pass
for o in [C(), D(), E(), F()]:
print type(o), type(o).mro(), type(o).__mro__
o.f()
try:
o.c()
except Exception, e:
print e
try:
o.d()
except Exception, e:
print e
# Testing invalid multiple inheritance hierarchies:
# Conflicting MRO:
try:
class G(E, F):
pass
except TypeError, e:
# This is silly but I think actually reasonable: the error message for this case is implementation-specific,
# since it depends on dict ordering rules (says either "for bases E, F" or "for bases F, E", depending on ordering).
# Canonicalize the error message by sorting the characters in it:
print ''.join(sorted(e.message)).strip()
# Conflicting MRO:
try:
class H(C, F):
pass
except TypeError, e:
print ''.join(sorted(e.message)).strip()
# "instance lay-out conflict"
try:
class I(str, int):
pass
except TypeError, e:
print e
# Testing the way super() behaves with multiple inheritance:
class S(C, D):
n = 3
def c(self):
print "S.c()"
super(S, self).c()
def d(self):
print "S.d()"
super(S, self).d()
def f(self):
print "S.f()"
print self.n, super(S, self).n, super(C, self).n
# TODO: Pyston doesn't support the full super.__getattribute__, so this will abort
# rather than throw an exception:
# try:
# print super(D, self).n
# except Exception as e:
# print e
super(S, self).f()
super(C, self).f()
s = S()
s.c()
s.d()
s.f()
for cls in [object, tuple, list, type, int, bool]:
print cls.__mro__
...@@ -5,6 +5,9 @@ class B(object): ...@@ -5,6 +5,9 @@ class B(object):
o.arg1 = arg1 o.arg1 = arg1
return o return o
def f(self):
print "B.f()"
class C(B): class C(B):
def __new__(cls, arg1, arg2): def __new__(cls, arg1, arg2):
print "C.__new__", arg2 print "C.__new__", arg2
...@@ -13,9 +16,14 @@ class C(B): ...@@ -13,9 +16,14 @@ class C(B):
print super(C, cls), super(C, o) print super(C, cls), super(C, o)
return o return o
def f(self):
print "C.f()"
super(C, self).f()
c = C(1, 2) c = C(1, 2)
print c.arg1 print c.arg1
print c.arg2 print c.arg2
c.f()
try: try:
super(1) super(1)
......
...@@ -413,16 +413,16 @@ if __name__ == "__main__": ...@@ -413,16 +413,16 @@ if __name__ == "__main__":
] ]
tests += big_tests tests += big_tests
LIB_DIR = os.path.join(sys.prefix, "lib/python2.7")
for t in tests: for t in tests:
bn = os.path.basename(t) bn = os.path.basename(t)
assert bn.endswith(".py") assert bn.endswith(".py")
module_name = bn[:-3] module_name = bn[:-3]
try:
__import__(module_name) if os.path.exists(os.path.join(LIB_DIR, module_name)) or \
os.path.exists(os.path.join(LIB_DIR, module_name + ".py")) or \
module_name in sys.builtin_module_names:
raise Exception("Error: %s hides builtin module '%s'" % (t, module_name)) raise Exception("Error: %s hides builtin module '%s'" % (t, module_name))
except ImportError:
pass
# good
for t in TOSKIP: for t in TOSKIP:
assert t in ("%s/t.py" % TEST_DIR, "%s/t2.py" % TEST_DIR) or t in tests, t assert t in ("%s/t.py" % TEST_DIR, "%s/t2.py" % TEST_DIR) or t in tests, t
......
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