Commit 3dba07f5 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #519 from kmod/sqlalchemy_tests

Sqlalchemy tests
parents f9d0c170 d9b9ca66
...@@ -20,3 +20,6 @@ ...@@ -20,3 +20,6 @@
path = test/integration/gflags path = test/integration/gflags
url = https://github.com/google/python-gflags url = https://github.com/google/python-gflags
ignore = untracked ignore = untracked
[submodule "test/integration/sqlalchemy"]
path = test/integration/sqlalchemy
url = https://github.com/zzzeek/sqlalchemy
...@@ -843,7 +843,10 @@ Value ASTInterpreter::visit_assert(AST_Assert* node) { ...@@ -843,7 +843,10 @@ Value ASTInterpreter::visit_assert(AST_Assert* node) {
Value v = visit_expr(node->test); Value v = visit_expr(node->test);
assert(v.o->cls == int_cls && static_cast<BoxedInt*>(v.o)->n == 0); assert(v.o->cls == int_cls && static_cast<BoxedInt*>(v.o)->n == 0);
#endif #endif
assertFail(source_info->parent_module, node->msg ? visit_expr(node->msg).o : 0);
static std::string AssertionError_str("AssertionError");
Box* assertion_type = getGlobal(globals, &AssertionError_str);
assertFail(assertion_type, node->msg ? visit_expr(node->msg).o : 0);
return Value(); return Value();
} }
......
...@@ -1660,6 +1660,7 @@ private: ...@@ -1660,6 +1660,7 @@ private:
} }
void doAssert(AST_Assert* node, UnwindInfo unw_info) { void doAssert(AST_Assert* node, UnwindInfo unw_info) {
// cfg translates all asserts into only 'assert 0' on the failing path.
AST_expr* test = node->test; AST_expr* test = node->test;
assert(test->type == AST_TYPE::Num); assert(test->type == AST_TYPE::Num);
AST_Num* num = ast_cast<AST_Num>(test); AST_Num* num = ast_cast<AST_Num>(test);
...@@ -1667,7 +1668,12 @@ private: ...@@ -1667,7 +1668,12 @@ private:
assert(num->n_int == 0); assert(num->n_int == 0);
std::vector<llvm::Value*> llvm_args; std::vector<llvm::Value*> llvm_args;
llvm_args.push_back(embedParentModulePtr());
// We could patchpoint this or try to avoid the overhead, but this should only
// happen when the assertion is actually thrown so I don't think it will be necessary.
static std::string AssertionError_str("AssertionError");
llvm_args.push_back(emitter.createCall2(unw_info, g.funcs.getGlobal, embedParentModulePtr(),
embedRelocatablePtr(&AssertionError_str, g.llvm_str_type_ptr)));
ConcreteCompilerVariable* converted_msg = NULL; ConcreteCompilerVariable* converted_msg = NULL;
if (node->msg) { if (node->msg) {
......
...@@ -264,6 +264,7 @@ public: ...@@ -264,6 +264,7 @@ public:
typedef std::vector<CompiledFunction*> FunctionList; typedef std::vector<CompiledFunction*> FunctionList;
struct CallRewriteArgs; struct CallRewriteArgs;
class BoxedCode;
class CLFunction { class CLFunction {
public: public:
int num_args; int num_args;
...@@ -278,6 +279,9 @@ public: ...@@ -278,6 +279,9 @@ public:
CompiledFunction* always_use_version; // if this version is set, always use it (for unboxed cases) CompiledFunction* always_use_version; // if this version is set, always use it (for unboxed cases)
std::unordered_map<const OSREntryDescriptor*, CompiledFunction*> osr_versions; std::unordered_map<const OSREntryDescriptor*, CompiledFunction*> osr_versions;
// Please use codeForFunction() to access this:
BoxedCode* code_obj;
// Functions can provide an "internal" version, which will get called instead // Functions can provide an "internal" version, which will get called instead
// of the normal dispatch through the functionlist. // of the normal dispatch through the functionlist.
// This can be used to implement functions which know how to rewrite themselves, // This can be used to implement functions which know how to rewrite themselves,
...@@ -289,12 +293,12 @@ public: ...@@ -289,12 +293,12 @@ public:
CLFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs, CLFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs,
std::unique_ptr<SourceInfo> source) std::unique_ptr<SourceInfo> source)
: num_args(num_args), num_defaults(num_defaults), takes_varargs(takes_varargs), takes_kwargs(takes_kwargs), : num_args(num_args), num_defaults(num_defaults), takes_varargs(takes_varargs), takes_kwargs(takes_kwargs),
source(std::move(source)), param_names(this->source->ast), always_use_version(NULL) { source(std::move(source)), param_names(this->source->ast), always_use_version(NULL), code_obj(NULL) {
assert(num_args >= num_defaults); assert(num_args >= num_defaults);
} }
CLFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs, const ParamNames& param_names) CLFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs, const ParamNames& param_names)
: num_args(num_args), num_defaults(num_defaults), takes_varargs(takes_varargs), takes_kwargs(takes_kwargs), : num_args(num_args), num_defaults(num_defaults), takes_varargs(takes_varargs), takes_kwargs(takes_kwargs),
source(nullptr), param_names(param_names), always_use_version(NULL) { source(nullptr), param_names(param_names), always_use_version(NULL), code_obj(NULL) {
assert(num_args >= num_defaults); assert(num_args >= num_defaults);
} }
...@@ -612,7 +616,7 @@ class BoxedClass; ...@@ -612,7 +616,7 @@ class BoxedClass;
// TODO these shouldn't be here // TODO these shouldn't be here
void setupRuntime(); void setupRuntime();
void teardownRuntime(); void teardownRuntime();
BoxedModule* createAndRunModule(const std::string& name, const std::string& fn); Box* createAndRunModule(const std::string& name, const std::string& fn);
BoxedModule* createModule(const std::string& name, const std::string& fn, const char* doc = NULL); BoxedModule* createModule(const std::string& name, const std::string& fn, const char* doc = NULL);
// TODO where to put this // TODO where to put this
......
...@@ -474,6 +474,11 @@ void setupSys() { ...@@ -474,6 +474,11 @@ void setupSys() {
ADD(optimize); ADD(optimize);
#undef ADD #undef ADD
#define SET_SYS_FROM_STRING(key, value) sys_module->giveAttr((key), (value))
#ifdef Py_USING_UNICODE
SET_SYS_FROM_STRING("maxunicode", PyInt_FromLong(PyUnicode_GetMax()));
#endif
sys_flags_cls->tp_mro = BoxedTuple::create({ sys_flags_cls, object_cls }); sys_flags_cls->tp_mro = BoxedTuple::create({ sys_flags_cls, object_cls });
sys_flags_cls->freeze(); sys_flags_cls->freeze();
......
...@@ -102,12 +102,17 @@ public: ...@@ -102,12 +102,17 @@ public:
} }
}; };
Box* codeForFunction(BoxedFunction* f) { Box* codeForCLFunction(CLFunction* f) {
return new BoxedCode(f->f); if (!f->code_obj) {
f->code_obj = new BoxedCode(f);
// CLFunctions don't currently participate in GC. They actually never get freed currently.
gc::registerPermanentRoot(f->code_obj);
}
return f->code_obj;
} }
Box* codeForCLFunction(CLFunction* f) { Box* codeForFunction(BoxedFunction* f) {
return new BoxedCode(f); return codeForCLFunction(f->f);
} }
CLFunction* clfunctionFromCode(Box* code) { CLFunction* clfunctionFromCode(Box* code) {
......
...@@ -39,7 +39,7 @@ static void removeModule(const std::string& name) { ...@@ -39,7 +39,7 @@ static void removeModule(const std::string& name) {
d->d.erase(b_name); d->d.erase(b_name);
} }
BoxedModule* createAndRunModule(const std::string& name, const std::string& fn) { Box* createAndRunModule(const std::string& name, const std::string& fn) {
BoxedModule* module = createModule(name, fn); BoxedModule* module = createModule(name, fn);
AST_Module* ast = caching_parse_file(fn.c_str()); AST_Module* ast = caching_parse_file(fn.c_str());
...@@ -49,10 +49,14 @@ BoxedModule* createAndRunModule(const std::string& name, const std::string& fn) ...@@ -49,10 +49,14 @@ BoxedModule* createAndRunModule(const std::string& name, const std::string& fn)
removeModule(name); removeModule(name);
raiseRaw(e); raiseRaw(e);
} }
return module;
Box* r = getSysModulesDict()->getOrNull(boxString(name));
if (!r)
raiseExcHelper(ImportError, "Loaded module %.200s not found in sys.modules", name.c_str());
return r;
} }
static BoxedModule* createAndRunModule(const std::string& name, const std::string& fn, const std::string& module_path) { static Box* createAndRunModule(const std::string& name, const std::string& fn, const std::string& module_path) {
BoxedModule* module = createModule(name, fn); BoxedModule* module = createModule(name, fn);
Box* b_path = boxStringPtr(&module_path); Box* b_path = boxStringPtr(&module_path);
...@@ -69,7 +73,11 @@ static BoxedModule* createAndRunModule(const std::string& name, const std::strin ...@@ -69,7 +73,11 @@ static BoxedModule* createAndRunModule(const std::string& name, const std::strin
removeModule(name); removeModule(name);
raiseRaw(e); raiseRaw(e);
} }
return module;
Box* r = getSysModulesDict()->getOrNull(boxString(name));
if (!r)
raiseExcHelper(ImportError, "Loaded module %.200s not found in sys.modules", name.c_str());
return r;
} }
#if LLVMREV < 210072 #if LLVMREV < 210072
...@@ -727,6 +735,15 @@ Box* impLoadModule(Box* _name, Box* _file, Box* _pathname, Box** args) { ...@@ -727,6 +735,15 @@ Box* impLoadModule(Box* _name, Box* _file, Box* _pathname, Box** args) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
Box* impLoadSource(Box* _name, Box* _pathname, Box* _file) {
RELEASE_ASSERT(!_file, "'file' argument not support yet");
RELEASE_ASSERT(_name->cls == str_cls, "");
RELEASE_ASSERT(_pathname->cls == str_cls, "");
return createAndRunModule(static_cast<BoxedString*>(_name)->s, static_cast<BoxedString*>(_pathname)->s);
}
Box* impLoadDynamic(Box* _name, Box* _pathname, Box* _file) { Box* impLoadDynamic(Box* _name, Box* _pathname, Box* _file) {
RELEASE_ASSERT(_name->cls == str_cls, ""); RELEASE_ASSERT(_name->cls == str_cls, "");
RELEASE_ASSERT(_pathname->cls == str_cls, ""); RELEASE_ASSERT(_pathname->cls == str_cls, "");
...@@ -796,6 +813,9 @@ void setupImport() { ...@@ -796,6 +813,9 @@ void setupImport() {
CLFunction* load_module_func = boxRTFunction((void*)impLoadModule, UNKNOWN, 4, CLFunction* load_module_func = boxRTFunction((void*)impLoadModule, UNKNOWN, 4,
ParamNames({ "name", "file", "pathname", "description" }, "", "")); ParamNames({ "name", "file", "pathname", "description" }, "", ""));
imp_module->giveAttr("load_module", new BoxedBuiltinFunctionOrMethod(load_module_func, "load_module")); imp_module->giveAttr("load_module", new BoxedBuiltinFunctionOrMethod(load_module_func, "load_module"));
imp_module->giveAttr(
"load_source", new BoxedBuiltinFunctionOrMethod(
boxRTFunction((void*)impLoadSource, UNKNOWN, 3, 1, false, false), "load_source", { NULL }));
CLFunction* load_dynamic_func = boxRTFunction((void*)impLoadDynamic, UNKNOWN, 3, 1, false, false, CLFunction* load_dynamic_func = boxRTFunction((void*)impLoadDynamic, UNKNOWN, 3, 1, false, false,
ParamNames({ "name", "pathname", "file" }, "", "")); ParamNames({ "name", "pathname", "file" }, "", ""));
......
...@@ -428,7 +428,7 @@ extern "C" Box* intAnd(BoxedInt* lhs, Box* rhs) { ...@@ -428,7 +428,7 @@ extern "C" Box* intAnd(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls)) if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__and__' requires a 'int' object but received a '%s'", getTypeName(lhs)); raiseExcHelper(TypeError, "descriptor '__and__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) { if (!isSubclass(rhs->cls, int_cls)) {
return NotImplemented; return NotImplemented;
} }
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
...@@ -445,7 +445,7 @@ extern "C" Box* intOr(BoxedInt* lhs, Box* rhs) { ...@@ -445,7 +445,7 @@ extern "C" Box* intOr(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls)) if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__or__' requires a 'int' object but received a '%s'", getTypeName(lhs)); raiseExcHelper(TypeError, "descriptor '__or__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) { if (!isSubclass(rhs->cls, int_cls)) {
return NotImplemented; return NotImplemented;
} }
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
...@@ -462,7 +462,7 @@ extern "C" Box* intXor(BoxedInt* lhs, Box* rhs) { ...@@ -462,7 +462,7 @@ extern "C" Box* intXor(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls)) if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__xor__' requires a 'int' object but received a '%s'", getTypeName(lhs)); raiseExcHelper(TypeError, "descriptor '__xor__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) { if (!isSubclass(rhs->cls, int_cls)) {
return NotImplemented; return NotImplemented;
} }
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
...@@ -590,7 +590,7 @@ extern "C" Box* intNe(BoxedInt* lhs, Box* rhs) { ...@@ -590,7 +590,7 @@ extern "C" Box* intNe(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls)) if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__ne__' requires a 'int' object but received a '%s'", getTypeName(lhs)); raiseExcHelper(TypeError, "descriptor '__ne__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) { if (!isSubclass(rhs->cls, int_cls)) {
return NotImplemented; return NotImplemented;
} }
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
...@@ -607,7 +607,7 @@ extern "C" Box* intLt(BoxedInt* lhs, Box* rhs) { ...@@ -607,7 +607,7 @@ extern "C" Box* intLt(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls)) if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__lt__' requires a 'int' object but received a '%s'", getTypeName(lhs)); raiseExcHelper(TypeError, "descriptor '__lt__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) { if (!isSubclass(rhs->cls, int_cls)) {
return NotImplemented; return NotImplemented;
} }
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
...@@ -624,7 +624,7 @@ extern "C" Box* intLe(BoxedInt* lhs, Box* rhs) { ...@@ -624,7 +624,7 @@ extern "C" Box* intLe(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls)) if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__le__' requires a 'int' object but received a '%s'", getTypeName(lhs)); raiseExcHelper(TypeError, "descriptor '__le__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) { if (!isSubclass(rhs->cls, int_cls)) {
return NotImplemented; return NotImplemented;
} }
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
...@@ -641,7 +641,7 @@ extern "C" Box* intGt(BoxedInt* lhs, Box* rhs) { ...@@ -641,7 +641,7 @@ extern "C" Box* intGt(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls)) if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__gt__' requires a 'int' object but received a '%s'", getTypeName(lhs)); raiseExcHelper(TypeError, "descriptor '__gt__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) { if (!isSubclass(rhs->cls, int_cls)) {
return NotImplemented; return NotImplemented;
} }
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
...@@ -658,7 +658,7 @@ extern "C" Box* intGe(BoxedInt* lhs, Box* rhs) { ...@@ -658,7 +658,7 @@ extern "C" Box* intGe(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls)) if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__ge__' requires a 'int' object but received a '%s'", getTypeName(lhs)); raiseExcHelper(TypeError, "descriptor '__ge__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) { if (!isSubclass(rhs->cls, int_cls)) {
return NotImplemented; return NotImplemented;
} }
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
...@@ -689,7 +689,7 @@ extern "C" Box* intLShift(BoxedInt* lhs, Box* rhs) { ...@@ -689,7 +689,7 @@ extern "C" Box* intLShift(BoxedInt* lhs, Box* rhs) {
if (rhs->cls == long_cls) if (rhs->cls == long_cls)
return longLshift(boxLong(lhs->n), rhs); return longLshift(boxLong(lhs->n), rhs);
if (rhs->cls != int_cls) { if (!isSubclass(rhs->cls, int_cls)) {
return NotImplemented; return NotImplemented;
} }
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
...@@ -706,7 +706,7 @@ extern "C" Box* intMod(BoxedInt* lhs, Box* rhs) { ...@@ -706,7 +706,7 @@ extern "C" Box* intMod(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls)) if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__mod__' requires a 'int' object but received a '%s'", getTypeName(lhs)); raiseExcHelper(TypeError, "descriptor '__mod__' requires a 'int' object but received a '%s'", getTypeName(lhs));
if (rhs->cls != int_cls) { if (!isSubclass(rhs->cls, int_cls)) {
return NotImplemented; return NotImplemented;
} }
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
...@@ -812,7 +812,7 @@ extern "C" Box* intRShift(BoxedInt* lhs, Box* rhs) { ...@@ -812,7 +812,7 @@ extern "C" Box* intRShift(BoxedInt* lhs, Box* rhs) {
if (rhs->cls == long_cls) if (rhs->cls == long_cls)
return longRshift(boxLong(lhs->n), rhs); return longRshift(boxLong(lhs->n), rhs);
if (rhs->cls != int_cls) { if (!isSubclass(rhs->cls, int_cls)) {
return NotImplemented; return NotImplemented;
} }
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
......
...@@ -220,12 +220,13 @@ extern "C" bool isSubclass(BoxedClass* child, BoxedClass* parent) { ...@@ -220,12 +220,13 @@ extern "C" bool isSubclass(BoxedClass* child, BoxedClass* parent) {
return PyType_IsSubtype(child, parent); return PyType_IsSubtype(child, parent);
} }
extern "C" void assertFail(BoxedModule* inModule, Box* msg) { extern "C" void assertFail(Box* assertion_type, Box* msg) {
RELEASE_ASSERT(assertion_type->cls == type_cls, "%s", assertion_type->cls->tp_name);
if (msg) { if (msg) {
BoxedString* tostr = str(msg); BoxedString* tostr = str(msg);
raiseExcHelper(AssertionError, "%s", tostr->data()); raiseExcHelper(static_cast<BoxedClass*>(assertion_type), "%s", tostr->data());
} else { } else {
raiseExcHelper(AssertionError, ""); raiseExcHelper(static_cast<BoxedClass*>(assertion_type), "");
} }
} }
......
...@@ -83,7 +83,7 @@ extern "C" Box* importStar(Box* from_module, BoxedModule* to_module); ...@@ -83,7 +83,7 @@ extern "C" Box* importStar(Box* from_module, BoxedModule* to_module);
extern "C" Box** unpackIntoArray(Box* obj, int64_t expected_size); extern "C" Box** unpackIntoArray(Box* obj, int64_t expected_size);
extern "C" void assertNameDefined(bool b, const char* name, BoxedClass* exc_cls, bool local_var_msg); extern "C" void assertNameDefined(bool b, const char* name, BoxedClass* exc_cls, bool local_var_msg);
extern "C" void assertFailDerefNameDefined(const char* name); extern "C" void assertFailDerefNameDefined(const char* name);
extern "C" void assertFail(BoxedModule* inModule, Box* msg); extern "C" void assertFail(Box* assertion_type, Box* msg);
extern "C" bool isSubclass(BoxedClass* child, BoxedClass* parent); extern "C" bool isSubclass(BoxedClass* child, BoxedClass* parent);
extern "C" BoxedClosure* createClosure(BoxedClosure* parent_closure, size_t size); extern "C" BoxedClosure* createClosure(BoxedClosure* parent_closure, size_t size);
......
...@@ -292,7 +292,11 @@ static BoxedSet* setIntersection2(BoxedSet* self, Box* container) { ...@@ -292,7 +292,11 @@ static BoxedSet* setIntersection2(BoxedSet* self, Box* container) {
static Box* setIssubset(BoxedSet* self, Box* container) { static Box* setIssubset(BoxedSet* self, Box* container) {
assert(self->cls == set_cls); assert(self->cls == set_cls);
RELEASE_ASSERT(container->cls == set_cls, "");
if (container->cls != set_cls && container->cls != frozenset_cls) {
container = setNew(set_cls, container);
}
assert(container->cls == set_cls || container->cls == frozenset_cls);
BoxedSet* rhs = static_cast<BoxedSet*>(container); BoxedSet* rhs = static_cast<BoxedSet*>(container);
for (auto e : self->s) { for (auto e : self->s) {
...@@ -304,7 +308,11 @@ static Box* setIssubset(BoxedSet* self, Box* container) { ...@@ -304,7 +308,11 @@ static Box* setIssubset(BoxedSet* self, Box* container) {
static Box* setIssuperset(BoxedSet* self, Box* container) { static Box* setIssuperset(BoxedSet* self, Box* container) {
assert(self->cls == set_cls); assert(self->cls == set_cls);
RELEASE_ASSERT(container->cls == set_cls, "");
if (container->cls != set_cls && container->cls != frozenset_cls) {
container = setNew(set_cls, container);
}
assert(container->cls == set_cls || container->cls == frozenset_cls);
BoxedSet* rhs = static_cast<BoxedSet*>(container); BoxedSet* rhs = static_cast<BoxedSet*>(container);
for (auto e : rhs->s) { for (auto e : rhs->s) {
......
...@@ -101,6 +101,9 @@ void raiseRaw(const ExcInfo& e) { ...@@ -101,6 +101,9 @@ void raiseRaw(const ExcInfo& e) {
assert(e.type); assert(e.type);
assert(e.value); assert(e.value);
assert(e.traceback); assert(e.traceback);
assert(gc::isValidGCObject(e.type));
assert(gc::isValidGCObject(e.value));
assert(gc::isValidGCObject(e.traceback));
// Using libgcc: // Using libgcc:
throw e; throw e;
......
...@@ -397,14 +397,6 @@ static void functionDtor(Box* b) { ...@@ -397,14 +397,6 @@ static void functionDtor(Box* b) {
self->dependent_ics.~ICInvalidator(); self->dependent_ics.~ICInvalidator();
} }
// TODO(kmod): builtin modules are not supposed to have a __file__ attribute
BoxedModule::BoxedModule(const std::string& name, const std::string& fn, const char* doc)
: attrs(HiddenClass::makeSingleton()) {
this->giveAttr("__name__", boxString(name));
this->giveAttr("__file__", boxString(fn));
this->giveAttr("__doc__", doc ? boxStrConstant(doc) : None);
}
std::string BoxedModule::name() { std::string BoxedModule::name() {
Box* name = this->getattr("__name__"); Box* name = this->getattr("__name__");
if (!name || name->cls != str_cls) { if (!name || name->cls != str_cls) {
...@@ -846,7 +838,6 @@ static Box* builtinFunctionOrMethodName(Box* b, void*) { ...@@ -846,7 +838,6 @@ static Box* builtinFunctionOrMethodName(Box* b, void*) {
static Box* functionCode(Box* self, void*) { static Box* functionCode(Box* self, void*) {
assert(self->cls == function_cls); assert(self->cls == function_cls);
BoxedFunction* func = static_cast<BoxedFunction*>(self); BoxedFunction* func = static_cast<BoxedFunction*>(self);
// This fails "f.func_code is f.func_code"
return codeForFunction(func); return codeForFunction(func);
} }
...@@ -1240,15 +1231,19 @@ Box* typeMro(BoxedClass* self) { ...@@ -1240,15 +1231,19 @@ Box* typeMro(BoxedClass* self) {
return r; return r;
} }
Box* moduleNew(BoxedClass* cls, BoxedString* name, BoxedString* fn) { Box* moduleInit(BoxedModule* self, Box* name, Box* doc) {
RELEASE_ASSERT(isSubclass(cls, module_cls), ""); RELEASE_ASSERT(isSubclass(self->cls, module_cls), "");
RELEASE_ASSERT(name->cls == str_cls, ""); RELEASE_ASSERT(name->cls == str_cls, "");
RELEASE_ASSERT(!fn || fn->cls == str_cls, ""); RELEASE_ASSERT(!doc || doc->cls == str_cls, "");
if (fn) HCAttrs* attrs = self->getHCAttrsPtr();
return new (cls) BoxedModule(name->s, fn->s); RELEASE_ASSERT(attrs->hcls->attributeArraySize() == 0, "");
else attrs->hcls = HiddenClass::makeSingleton();
return new (cls) BoxedModule(name->s, "__builtin__");
self->giveAttr("__name__", name);
self->giveAttr("__doc__", doc ? doc : boxString(""));
return None;
} }
Box* moduleRepr(BoxedModule* m) { Box* moduleRepr(BoxedModule* m) {
...@@ -2379,8 +2374,8 @@ void setupRuntime() { ...@@ -2379,8 +2374,8 @@ void setupRuntime() {
none_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)noneNonzero, BOXED_BOOL, 1))); none_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)noneNonzero, BOXED_BOOL, 1)));
none_cls->freeze(); none_cls->freeze();
module_cls->giveAttr("__new__", module_cls->giveAttr("__init__",
new BoxedFunction(boxRTFunction((void*)moduleNew, UNKNOWN, 3, 1, false, false), { NULL })); new BoxedFunction(boxRTFunction((void*)moduleInit, UNKNOWN, 3, 1, false, false), { NULL }));
module_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)moduleRepr, STR, 1))); module_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)moduleRepr, STR, 1)));
module_cls->giveAttr("__dict__", dict_descr); module_cls->giveAttr("__dict__", dict_descr);
module_cls->freeze(); module_cls->freeze();
...@@ -2428,6 +2423,7 @@ void setupRuntime() { ...@@ -2428,6 +2423,7 @@ void setupRuntime() {
new BoxedFunction(boxRTFunction((void*)functionCall, UNKNOWN, 1, 0, true, true))); new BoxedFunction(boxRTFunction((void*)functionCall, UNKNOWN, 1, 0, true, true)));
function_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)functionNonzero, BOXED_BOOL, 1))); function_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)functionNonzero, BOXED_BOOL, 1)));
function_cls->giveAttr("func_code", new (pyston_getset_cls) BoxedGetsetDescriptor(functionCode, NULL, NULL)); function_cls->giveAttr("func_code", new (pyston_getset_cls) BoxedGetsetDescriptor(functionCode, NULL, NULL));
function_cls->giveAttr("__code__", function_cls->getattr("func_code"));
function_cls->giveAttr("func_name", function_cls->getattr("__name__")); function_cls->giveAttr("func_name", function_cls->getattr("__name__"));
function_cls->giveAttr("func_defaults", function_cls->giveAttr("func_defaults",
new (pyston_getset_cls) BoxedGetsetDescriptor(functionDefaults, functionSetDefaults, NULL)); new (pyston_getset_cls) BoxedGetsetDescriptor(functionDefaults, functionSetDefaults, NULL));
...@@ -2593,15 +2589,16 @@ BoxedModule* createModule(const std::string& name, const std::string& fn, const ...@@ -2593,15 +2589,16 @@ BoxedModule* createModule(const std::string& name, const std::string& fn, const
// Surprisingly, there are times that we need to return the existing module if // Surprisingly, there are times that we need to return the existing module if
// one exists: // one exists:
Box*& ptr = d->d[b_name]; Box* existing = d->getOrNull(b_name);
if (ptr && isSubclass(ptr->cls, module_cls)) { if (existing && isSubclass(existing->cls, module_cls)) {
return static_cast<BoxedModule*>(ptr); return static_cast<BoxedModule*>(existing);
} else {
ptr = NULL;
} }
BoxedModule* module = new BoxedModule(name, fn, doc); BoxedModule* module = new BoxedModule();
ptr = module; moduleInit(module, boxString(name), boxString(doc ? doc : ""));
module->giveAttr("__file__", boxString(fn));
d->d[b_name] = module;
return module; return module;
} }
......
...@@ -705,7 +705,7 @@ public: ...@@ -705,7 +705,7 @@ public:
FutureFlags future_flags; FutureFlags future_flags;
BoxedModule(const std::string& name, const std::string& fn, const char* doc = NULL); BoxedModule() {} // noop constructor to disable zero-initialization of cls
std::string name(); std::string name();
Box* getStringConstant(const std::string& ast_str); Box* getStringConstant(const std::string& ast_str);
......
Subproject commit eb1bb84fbc10c801c7269a3d38c9e0235327857e
# skip-if: True
# - getting to the point of running the sqlalchemy tests is quite hard, since there is a lot
# of pytest code that runs beforehand.
import os
import sys
import subprocess
import shutil
ENV_NAME = "sqlalchemy_test_env_" + os.path.basename(sys.executable)
if not os.path.exists(ENV_NAME) or os.stat(sys.executable).st_mtime > os.stat(ENV_NAME + "/bin/python").st_mtime:
print "Creating virtualenv to install testing dependencies..."
VIRTUALENV_SCRIPT = os.path.dirname(__file__) + "/virtualenv/virtualenv.py"
try:
args = [sys.executable, VIRTUALENV_SCRIPT, "-p", sys.executable, ENV_NAME]
print "Running", args
subprocess.check_call(args)
subprocess.check_call([ENV_NAME + "/bin/pip", "install", "mock", "pytest"])
except:
print "Error occurred; trying to remove partially-created directory"
ei = sys.exc_info()
try:
subprocess.check_call(["rm", "-rf", ENV_NAME])
except Exception as e:
print e
raise ei[0], ei[1], ei[2]
# subprocess.check_call([os.path.abspath("sqlalchemy_test_env/bin/python"), "-c", "import py; print type(py); print py.builtin"])
SQLALCHEMY_DIR = os.path.dirname(__file__) + "/sqlalchemy"
python_exe = os.path.abspath(ENV_NAME + "/bin/python")
# Exec'ing the test suite can be nice for debugging, but let's the subprocess version
# in case we want to do stuff afterwards:
do_exec = True
if do_exec:
print "About to exec"
os.chdir(SQLALCHEMY_DIR)
os.execl(python_exe, python_exe, "-m", "pytest")
else:
subprocess.check_call([python_exe, "-m", "pytest"], cwd=SQLALCHEMY_DIR)
print
print "PASSED"
...@@ -17,3 +17,6 @@ def f(): ...@@ -17,3 +17,6 @@ def f():
pass pass
print f.func_defaults print f.func_defaults
print f.func_code.co_firstlineno print f.func_code.co_firstlineno
# pytest uses this:
print f.__code__ is f.__code__
...@@ -16,3 +16,9 @@ for a in (1, "", "/proc", "nonexisting_dir"): ...@@ -16,3 +16,9 @@ for a in (1, "", "/proc", "nonexisting_dir"):
imp.acquire_lock() imp.acquire_lock()
imp.release_lock() imp.release_lock()
import os
print "first load_source():"
m1 = imp.load_source("import_target", os.path.join(os.path.dirname(__file__), "import_target.py"))
print "second load_source():"
m2 = imp.load_source("import_target", os.path.join(os.path.dirname(__file__), "import_target.py"))
print m1 is m2
...@@ -79,3 +79,11 @@ for b in range(26): ...@@ -79,3 +79,11 @@ for b in range(26):
print int(u'123', b) print int(u'123', b)
except ValueError as e: except ValueError as e:
print e print e
class I(int):
pass
for i1 in [1, I(2), 3, I(4)]:
for i2 in [1, I(2), 3, I(4)]:
print -i1, +i1, ~i1, i1 < i2, i1 <= i2, i1 == i2, i1 > i2, i1 >= i2, i1 != i2, i1 | i2, i1 ^ i2, i1 & i2, i1 * i2, i1 + i2, i1 / i2, i1 - i2, i1 ** i2, i1 // i2
from types import ModuleType from types import ModuleType
class MyModule(ModuleType): class MyModule(ModuleType):
pass # Make sure that we can override __init__:
def __init__(self, fn, doc, myarg):
super(MyModule, self).__init__(fn, doc)
self.myarg = myarg
print MyModule('o') print MyModule('o', "doc", 1)
orig_ae = AssertionError
class MyAssertionError(Exception):
pass
s = """
try:
assert 0
except Exception as e:
print type(e)
"""
exec s
import __builtin__
__builtin__.AssertionError = MyAssertionError
exec s
class MyAssertionError2(Exception):
pass
AssertionError = MyAssertionError2
exec s
exec s in {}
class MyAssertionError3(Exception):
pass
def f1():
# assert is hardcoded to look up "AssertionError" in the global scope,
# even if there is a store to it locally:
AssertionError = MyAssertionError3
exec s
try:
assert 0
except Exception as e:
print type(e)
f1()
...@@ -107,4 +107,4 @@ print s ...@@ -107,4 +107,4 @@ print s
s = set(range(5)) s = set(range(5))
for i in xrange(10): for i in xrange(10):
s2 = set(range(i)) s2 = set(range(i))
print s.issubset(s2), s.issuperset(s2), s == s2, s != s2, s.difference(s2) print s.issubset(s2), s.issuperset(s2), s == s2, s != s2, s.difference(s2), s.issubset(range(i)), s.issuperset(range(i))
# skip-if: True
import os
import sys
sys.modules[__name__] = os
import sys_modules_replacement_target
print hasattr(sys_modules_replacement_target, "path")
...@@ -152,3 +152,6 @@ for m in str.strip, str.lstrip, str.rstrip: ...@@ -152,3 +152,6 @@ for m in str.strip, str.lstrip, str.rstrip:
print repr(m(s, *args)) print repr(m(s, *args))
print "".join([u"\xB2", u"\xB3"]) print "".join([u"\xB2", u"\xB3"])
import sys
print type(sys.maxunicode)
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