Commit 53d6a680 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge branch 'distutils'

parents 954464cd b7d0a555
......@@ -939,6 +939,17 @@ $(TEST_DIR)/test_extension/%.pyston.so: $(TEST_DIR)/test_extension/%.o $(BUILD_S
$(TEST_DIR)/test_extension/%.o: $(TEST_DIR)/test_extension/%.c $(wildcard ./include/*.h) $(BUILD_SYSTEM_DEPS)
$(CLANG_EXE) -O2 -fPIC -Wimplicit -I./include -c $< -o $@ -g
.PHONY: ext_pyston_selfhost dbg_ext_pyston_selfhost ext_pyston_selfhost_release
ext_pyston_selfhost: pyston_dbg $(TEST_EXT_MODULE_NAMES:%=$(TEST_DIR)/test_extension/*.c)
cd $(TEST_DIR)/test_extension; DISTUTILS_DEBUG=1 time ../../pyston_dbg setup.py build
cd $(TEST_DIR)/test_extension; ln -sf $(TEST_EXT_MODULE_NAMES:%=build/lib.unknown-2.7/%.pyston.so) .
dbg_ext_pyston_selfhost: pyston_dbg $(TEST_EXT_MODULE_NAMES:%=$(TEST_DIR)/test_extension/*.c)
cd $(TEST_DIR)/test_extension; DISTUTILS_DEBUG=1 $(GDB) $(GDB_CMDS) --args ../../pyston_dbg setup.py build
cd $(TEST_DIR)/test_extension; ln -sf $(TEST_EXT_MODULE_NAMES:%=build/lib.unknown-2.7/%.pyston.so) .
ext_pyston_selfhost_release: pyston_release $(TEST_EXT_MODULE_NAMES:%=$(TEST_DIR)/test_extension/*.c)
cd $(TEST_DIR)/test_extension; DISTUTILS_DEBUG=1 time ../../pyston_release setup.py build
cd $(TEST_DIR)/test_extension; ln -sf $(TEST_EXT_MODULE_NAMES:%=build/lib.unknown-2.7/%.pyston.so) .
.PHONY: ext_python
ext_python: $(TEST_EXT_MODULE_NAMES:%=$(TEST_DIR)/test_extension/*.c)
cd $(TEST_DIR)/test_extension; python setup.py build
......
......@@ -34,7 +34,15 @@ PyAPI_DATA(int) Py_HashRandomizationFlag;
PYTHONPATH and PYTHONHOME from the environment */
#define Py_GETENV(s) (Py_IgnoreEnvironmentFlag ? NULL : getenv(s))
PyAPI_FUNC(void) Py_FatalError(const char *message) __attribute__((__noreturn__));
// Pyston change: make Py_FatalError a macro so that it can access linenumber info, similar to assert:
//PyAPI_FUNC(void) Py_FatalError(const char *message) __attribute__((__noreturn__));
#define _STRINGIFY(N) #N
#define STRINGIFY(N) _STRINGIFY(N)
#define Py_FatalError(message) \
do { \
fprintf(stderr, __FILE__ ":" STRINGIFY(__LINE__) ": %s: Fatal Python error: %s\n", __PRETTY_FUNCTION__, message); \
abort(); \
} while (0)
#ifdef __cplusplus
}
......
......@@ -125,6 +125,36 @@ static PyObject* do_mkvalue(const char** p_format, va_list* p_va, int flags) noe
return v;
}
case 's':
case 'z': {
PyObject* v;
char* str = va_arg(*p_va, char*);
Py_ssize_t n;
if (**p_format == '#') {
++*p_format;
if (flags & FLAG_SIZE_T)
n = va_arg(*p_va, Py_ssize_t);
else
n = va_arg(*p_va, int);
} else
n = -1;
if (str == NULL) {
v = Py_None;
Py_INCREF(v);
} else {
if (n < 0) {
size_t m = strlen(str);
if (m > PY_SSIZE_T_MAX) {
PyErr_SetString(PyExc_OverflowError, "string too long for Python string");
return NULL;
}
n = (Py_ssize_t)m;
}
v = PyString_FromStringAndSize(str, n);
}
return v;
}
default:
RELEASE_ASSERT(0, "%c", *((*p_format) - 1));
}
......
......@@ -65,6 +65,7 @@ static AST_Name* makeName(const std::string& id, AST_TYPE::AST_TYPE ctx_type, in
class CFGVisitor : public ASTVisitor {
private:
AST_TYPE::AST_TYPE root_type;
FutureFlags future_flags;
CFG* cfg;
CFGBlock* curblock;
ScopingAnalysis* scoping_analysis;
......@@ -996,8 +997,8 @@ private:
}
public:
CFGVisitor(AST_TYPE::AST_TYPE root_type, ScopingAnalysis* scoping_analysis, CFG* cfg)
: root_type(root_type), cfg(cfg), scoping_analysis(scoping_analysis) {
CFGVisitor(AST_TYPE::AST_TYPE root_type, FutureFlags future_flags, ScopingAnalysis* scoping_analysis, CFG* cfg)
: root_type(root_type), future_flags(future_flags), cfg(cfg), scoping_analysis(scoping_analysis) {
curblock = cfg->addBlock();
curblock->info = "entry";
}
......@@ -1194,7 +1195,15 @@ public:
import->args.push_back(new AST_Num());
static_cast<AST_Num*>(import->args[0])->num_type = AST_Num::INT;
static_cast<AST_Num*>(import->args[0])->n_int = node->level;
// I don't quite understand this but this is what CPython does:
int level;
if (node->level == 0 && !(future_flags & FF_ABSOLUTE_IMPORT))
level = -1;
else
level = node->level;
static_cast<AST_Num*>(import->args[0])->n_int = level;
import->args.push_back(new AST_Tuple());
static_cast<AST_Tuple*>(import->args[1])->ctx_type = AST_TYPE::Load;
for (int i = 0; i < node->names.size(); i++) {
......@@ -2019,7 +2028,7 @@ CFG* computeCFG(SourceInfo* source, std::vector<AST_stmt*> body) {
ScopingAnalysis* scoping_analysis = source->scoping;
CFGVisitor visitor(source->ast->type, scoping_analysis, rtn);
CFGVisitor visitor(source->ast->type, source->parent_module->future_flags, scoping_analysis, rtn);
bool skip_first = false;
......
......@@ -48,6 +48,10 @@ extern "C" Box* boolRepr(BoxedBool* v) {
return boxStrConstant("False");
}
extern "C" Box* boolHash(BoxedBool* v) {
return boxInt(v == True);
}
extern "C" Box* boolNew(Box* cls, Box* val) {
assert(cls == bool_cls);
......@@ -64,6 +68,7 @@ void setupBool() {
bool_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)boolNonzero, BOXED_BOOL, 1)));
bool_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)boolRepr, STR, 1)));
bool_cls->giveAttr("__str__", bool_cls->getattr("__repr__"));
bool_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)boolHash, BOXED_INT, 1)));
bool_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)boolNew, UNKNOWN, 2, 1, false, false), { None }));
......
......@@ -26,7 +26,9 @@
#include "core/ast.h"
#include "core/types.h"
#include "gc/collector.h"
#include "runtime/classobj.h"
#include "runtime/ics.h"
#include "runtime/import.h"
#include "runtime/inline/xrange.h"
#include "runtime/list.h"
#include "runtime/long.h"
......@@ -338,6 +340,10 @@ Box* isinstance_func(Box* obj, Box* cls) {
}
Box* issubclass_func(Box* child, Box* parent) {
if (parent->cls == classobj_cls) {
Py_FatalError("don't handle issubclass for old style classes yet");
}
RELEASE_ASSERT(child->cls == type_cls, "");
// TODO parent can also be a tuple of classes
RELEASE_ASSERT(parent->cls == type_cls, "");
......@@ -345,6 +351,14 @@ Box* issubclass_func(Box* child, Box* parent) {
return boxBool(isSubclass(static_cast<BoxedClass*>(child), static_cast<BoxedClass*>(parent)));
}
Box* bltinImport(Box* arg) {
if (arg->cls != str_cls) {
raiseExcHelper(TypeError, "__import__() argument 1 must be string, not %s", getTypeName(arg)->c_str());
}
return import(-1, new BoxedTuple({}), &static_cast<BoxedString*>(arg)->s);
}
Box* getattrFunc(Box* obj, Box* _str, Box* default_value) {
if (_str->cls != str_cls) {
raiseExcHelper(TypeError, "getattr(): attribute name must be string");
......@@ -805,6 +819,7 @@ void setupBuiltins() {
Box* issubclass_obj = new BoxedFunction(boxRTFunction((void*)issubclass_func, BOXED_BOOL, 2));
builtins_module->giveAttr("issubclass", issubclass_obj);
builtins_module->giveAttr("__import__", new BoxedFunction(boxRTFunction((void*)bltinImport, UNKNOWN, 1)));
enumerate_cls
= new BoxedHeapClass(type_cls, object_cls, &BoxedEnumerate::gcHandler, 0, sizeof(BoxedEnumerate), false);
......
......@@ -132,13 +132,6 @@ extern "C" void PyBuffer_Release(Py_buffer* view) {
view->obj = NULL;
}
// Not sure why we need another declaration here:
extern "C" void Py_FatalError(const char* msg) __attribute__((__noreturn__));
extern "C" void Py_FatalError(const char* msg) {
fprintf(stderr, "\nFatal Python error: %s\n", msg);
abort();
}
extern "C" void _PyErr_BadInternalCall(const char* filename, int lineno) {
Py_FatalError("unimplemented");
}
......
......@@ -106,6 +106,11 @@ static BoxedModule* importFile(const std::string& name, const std::string& full_
}
static Box* importSub(const std::string& name, const std::string& full_name, Box* parent_module) {
Box* boxed_name = boxStringPtr(&full_name);
BoxedDict* sys_modules = getSysModulesDict();
if (sys_modules->d.find(boxed_name) != sys_modules->d.end())
return sys_modules->d[boxed_name];
BoxedList* path_list;
if (parent_module == NULL) {
path_list = getSysPath();
......@@ -172,15 +177,10 @@ static Box* import(const std::string* name, bool return_first) {
}
std::string prefix_name = std::string(*name, 0, r);
Box* s = boxStringPtr(&prefix_name);
if (sys_modules->d.find(s) != sys_modules->d.end()) {
last_module = sys_modules->d[s];
} else {
std::string small_name = std::string(*name, l, r - l);
last_module = importSub(small_name, prefix_name, last_module);
if (!last_module)
raiseExcHelper(ImportError, "No module named %s", small_name.c_str());
}
std::string small_name = std::string(*name, l, r - l);
last_module = importSub(small_name, prefix_name, last_module);
if (!last_module)
raiseExcHelper(ImportError, "No module named %s", small_name.c_str());
if (l == 0) {
first_module = last_module;
......@@ -225,6 +225,8 @@ static void ensure_fromlist(Box* module, Box* fromlist, const std::string& modul
}
extern "C" Box* import(int level, Box* from_imports, const std::string* module_name) {
RELEASE_ASSERT(level == -1, "");
Box* module = import(module_name, from_imports == None);
assert(module);
......
......@@ -680,6 +680,8 @@ extern "C" Box* intNew(Box* _cls, Box* val) {
double d = static_cast<BoxedFloat*>(val)->d;
rtn->n = d;
} else if (val->cls == bool_cls) {
rtn->n = (val == True);
} else {
fprintf(stderr, "TypeError: int() argument must be a string or a number, not '%s'\n",
getTypeName(val)->c_str());
......
......@@ -838,7 +838,7 @@ Box* strEndswith(BoxedString* self, Box* elt) {
return boxBool(endswith(self->s, sub->s));
}
Box* strFind(BoxedString* self, Box* elt) {
Box* strFind(BoxedString* self, Box* elt, Box* _start) {
if (self->cls != str_cls)
raiseExcHelper(TypeError, "descriptor 'find' requires a 'str' object but received a '%s'",
getTypeName(elt)->c_str());
......@@ -846,9 +846,21 @@ Box* strFind(BoxedString* self, Box* elt) {
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
if (_start->cls != int_cls) {
raiseExcHelper(TypeError, "'start' must be an int for now");
// Real error message:
// raiseExcHelper(TypeError, "slice indices must be integers or None or have an __index__ method");
}
int64_t start = static_cast<BoxedInt*>(_start)->n;
if (start < 0) {
start += self->s.size();
start = std::max(0L, start);
}
BoxedString* sub = static_cast<BoxedString*>(elt);
size_t r = self->s.find(sub->s);
size_t r = self->s.find(sub->s, start);
if (r == std::string::npos)
return boxInt(-1);
return boxInt(r);
......@@ -1085,7 +1097,8 @@ void setupStr() {
str_cls->giveAttr("startswith", new BoxedFunction(boxRTFunction((void*)strStartswith, BOXED_BOOL, 2)));
str_cls->giveAttr("endswith", new BoxedFunction(boxRTFunction((void*)strEndswith, BOXED_BOOL, 2)));
str_cls->giveAttr("find", new BoxedFunction(boxRTFunction((void*)strFind, BOXED_INT, 2)));
str_cls->giveAttr("find",
new BoxedFunction(boxRTFunction((void*)strFind, BOXED_INT, 3, 1, false, false), { boxInt(0) }));
str_cls->giveAttr("rfind", new BoxedFunction(boxRTFunction((void*)strRfind, BOXED_INT, 2)));
str_cls->giveAttr("__add__", new BoxedFunction(boxRTFunction((void*)strAdd, UNKNOWN, 2)));
......
......@@ -981,7 +981,7 @@ BoxedModule* createModule(const std::string& name, const std::string& fn) {
BoxedDict* d = getSysModulesDict();
Box* b_name = boxStringPtr(&name);
assert(d->d.count(b_name) == 0);
ASSERT(d->d.count(b_name) == 0, "%s", name.c_str());
d->d[b_name] = module;
module->giveAttr("__doc__", None);
......
......@@ -26,6 +26,9 @@ class C(object):
def __repr__(self):
return "<C object>"
print hash(True) == hash(False)
print int(True), int(False)
c = C("hello") # This object has an invalid __nonzero__ return type
if 0:
print bool(c) # this will fail
......
......@@ -27,3 +27,5 @@ print import_nested_target.y
print z
print y
print __name__
print __import__("import_target") is import_target
......@@ -69,3 +69,6 @@ for c in "aeiou":
translation_map = ''.join(translation_map)
print "hello world".translate(translation_map)
print "hello world".translate(translation_map, "")
for i in xrange(-10, 10):
print i, "aaaaa".find("a", i)
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