extern "C" int PySys_SetObject(const char* name, PyObject* v) noexcept { try { if (!v) { if (sys_module->getattr(autoDecref(internStringMortal(name)))) sys_module->delattr(autoDecref(internStringMortal(name)), NULL); } else sys_module->setattr(autoDecref(internStringMortal(name)), v, NULL); } catch (ExcInfo e) { abort(); } return 0; }
void setupThread() { // Hacky: we want to use some of CPython's implementation of the thread module (the threading local stuff), // and some of ours (thread handling). Start off by calling a cut-down version of initthread, and then // add our own attributes to the module it creates. initthread(); RELEASE_ASSERT(!PyErr_Occurred(), ""); Box* thread_module = getSysModulesDict()->getOrNull(boxString("thread")); assert(thread_module); thread_module->giveAttr("start_new_thread", new BoxedBuiltinFunctionOrMethod( boxRTFunction((void*)startNewThread, BOXED_INT, 3, 1, false, false), "start_new_thread", { NULL })); thread_module->giveAttr("allocate_lock", new BoxedBuiltinFunctionOrMethod( boxRTFunction((void*)allocateLock, UNKNOWN, 0), "allocate_lock")); thread_module->giveAttr( "get_ident", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)getIdent, BOXED_INT, 0), "get_ident")); thread_module->giveAttr( "stack_size", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)stackSize, BOXED_INT, 0), "stack_size")); thread_lock_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, 0, sizeof(BoxedThreadLock), false, "lock"); thread_lock_cls->tp_dealloc = BoxedThreadLock::threadLockDestructor; thread_lock_cls->has_safe_tp_dealloc = true; thread_lock_cls->giveAttr("__module__", boxString("thread")); thread_lock_cls->giveAttr( "acquire", new BoxedFunction(boxRTFunction((void*)BoxedThreadLock::acquire, BOXED_BOOL, 2, 1, false, false), { boxInt(1) })); thread_lock_cls->giveAttr("release", new BoxedFunction(boxRTFunction((void*)BoxedThreadLock::release, NONE, 1))); thread_lock_cls->giveAttr("acquire_lock", thread_lock_cls->getattr(internStringMortal("acquire"))); thread_lock_cls->giveAttr("release_lock", thread_lock_cls->getattr(internStringMortal("release"))); thread_lock_cls->giveAttr("__enter__", thread_lock_cls->getattr(internStringMortal("acquire"))); thread_lock_cls->giveAttr("__exit__", new BoxedFunction(boxRTFunction((void*)BoxedThreadLock::exit, NONE, 4))); thread_lock_cls->giveAttr("locked", new BoxedFunction(boxRTFunction((void*)BoxedThreadLock::locked, BOXED_BOOL, 1))); thread_lock_cls->giveAttr("locked_lock", thread_lock_cls->getattr(internStringMortal("locked"))); thread_lock_cls->freeze(); ThreadError = BoxedHeapClass::create(type_cls, Exception, NULL, Exception->attrs_offset, Exception->tp_weaklistoffset, Exception->tp_basicsize, false, "error"); ThreadError->giveAttr("__module__", boxString("thread")); ThreadError->freeze(); thread_module->giveAttr("error", ThreadError); }
BoxedList* getSysPath() { // Unlike sys.modules, CPython handles sys.path by fetching it each time: Box* _sys_path = sys_module->getattr(internStringMortal("path")); assert(_sys_path); if (_sys_path->cls != list_cls) { raiseExcHelper(RuntimeError, "sys.path must be a list of directory names"); } assert(_sys_path->cls == list_cls); return static_cast<BoxedList*>(_sys_path); }
static Box* importSub(const std::string& name, BoxedString* full_name, Box* parent_module) { BoxedDict* sys_modules = getSysModulesDict(); if (sys_modules->d.find(full_name) != sys_modules->d.end()) { return sys_modules->d[full_name]; } BoxedList* path_list; if (parent_module == NULL || parent_module == None) { path_list = NULL; } else { static BoxedString* path_str = internStringImmortal("__path__"); path_list = static_cast<BoxedList*>(getattrInternal<ExceptionStyle::CXX>(parent_module, path_str)); if (path_list == NULL || path_list->cls != list_cls) { return None; } } SearchResult sr = findModule(name, full_name, path_list); if (sr.type != SearchResult::SEARCH_ERROR) { Box* module; try { if (sr.type == SearchResult::PY_SOURCE) module = createAndRunModule(full_name, sr.path); else if (sr.type == SearchResult::PKG_DIRECTORY) module = createAndRunModule(full_name, sr.path + "/__init__.py", sr.path); else if (sr.type == SearchResult::C_EXTENSION) module = importCExtension(full_name, name, sr.path); else if (sr.type == SearchResult::IMP_HOOK) { static BoxedString* loadmodule_str = internStringImmortal("load_module"); CallattrFlags callattr_flags{.cls_only = false, .null_on_nonexistent = false, .argspec = ArgPassSpec(1) }; module = callattr(sr.loader, loadmodule_str, callattr_flags, full_name, NULL, NULL, NULL, NULL); } else RELEASE_ASSERT(0, "%d", sr.type); } catch (ExcInfo e) { removeModule(full_name); throw e; } if (parent_module && parent_module != None) parent_module->setattr(internStringMortal(name), module, NULL); return module; }
void setupSys() { sys_modules_dict = new BoxedDict(); constants.push_back(sys_modules_dict); // This is ok to call here because we've already created the sys_modules_dict sys_module = createModule(autoDecref(boxString("sys"))); // sys_module is what holds on to all of the other modules: Py_INCREF(sys_module); late_constants.push_back(sys_module); sys_module->giveAttrBorrowed("modules", sys_modules_dict); BoxedList* sys_path = new BoxedList(); constants.push_back(sys_path); sys_module->giveAttrBorrowed("path", sys_path); sys_module->giveAttr("argv", new BoxedList()); sys_module->giveAttr("exc_info", new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)sysExcInfo, BOXED_TUPLE, 0), "exc_info", exc_info_doc)); sys_module->giveAttr("exc_clear", new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)sysExcClear, NONE, 0), "exc_clear", exc_clear_doc)); sys_module->giveAttr( "exit", new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)sysExit, NONE, 1, false, false), "exit", { None }, NULL, exit_doc)); sys_module->giveAttr("warnoptions", new BoxedList()); sys_module->giveAttrBorrowed("py3kwarning", Py_False); sys_module->giveAttr("byteorder", boxString(isLittleEndian() ? "little" : "big")); sys_module->giveAttr("platform", boxString(Py_GetPlatform())); sys_module->giveAttr("executable", boxString(Py_GetProgramFullPath())); sys_module->giveAttr( "_getframe", new BoxedFunction(FunctionMetadata::create((void*)sysGetFrame, UNKNOWN, 1, false, false), { NULL })); sys_module->giveAttr("_current_frames", new BoxedFunction(FunctionMetadata::create((void*)sysCurrentFrames, UNKNOWN, 0))); sys_module->giveAttr("getdefaultencoding", new BoxedBuiltinFunctionOrMethod( FunctionMetadata::create((void*)sysGetDefaultEncoding, STR, 0), "getdefaultencoding", getdefaultencoding_doc)); sys_module->giveAttr("getfilesystemencoding", new BoxedBuiltinFunctionOrMethod( FunctionMetadata::create((void*)sysGetFilesystemEncoding, STR, 0), "getfilesystemencoding", getfilesystemencoding_doc)); sys_module->giveAttr("getrecursionlimit", new BoxedBuiltinFunctionOrMethod( FunctionMetadata::create((void*)sysGetRecursionLimit, UNKNOWN, 0), "getrecursionlimit", getrecursionlimit_doc)); // As we don't support compile() etc yet force 'dont_write_bytecode' to true. sys_module->giveAttrBorrowed("dont_write_bytecode", Py_True); sys_module->giveAttr("prefix", boxString(Py_GetPrefix())); sys_module->giveAttr("exec_prefix", boxString(Py_GetExecPrefix())); sys_module->giveAttr("copyright", boxString("Copyright 2014-2016 Dropbox.\nAll Rights Reserved.\n\nCopyright (c) 2001-2014 " "Python Software Foundation.\nAll Rights Reserved.\n\nCopyright (c) 2000 " "BeOpen.com.\nAll Rights Reserved.\n\nCopyright (c) 1995-2001 Corporation for " "National Research Initiatives.\nAll Rights Reserved.\n\nCopyright (c) " "1991-1995 Stichting Mathematisch Centrum, Amsterdam.\nAll Rights Reserved.")); sys_module->giveAttr("version", boxString(generateVersionString())); sys_module->giveAttr("hexversion", boxInt(PY_VERSION_HEX)); sys_module->giveAttr("subversion", BoxedTuple::create({ autoDecref(boxString("Pyston")), autoDecref(boxString("")), autoDecref(boxString("")) })); sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX)); sys_module->giveAttr("maxsize", boxInt(PY_SSIZE_T_MAX)); sys_flags_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSysFlags), false, "flags", false, NULL, NULL, false); sys_flags_cls->giveAttr( "__new__", new BoxedFunction(FunctionMetadata::create((void*)BoxedSysFlags::__new__, UNKNOWN, 1, true, true))); sys_flags_cls->tp_dealloc = (destructor)BoxedSysFlags::dealloc; #define ADD(name) sys_flags_cls->giveAttrMember(STRINGIFY(name), T_OBJECT, offsetof(BoxedSysFlags, name)); ADD(division_warning); ADD(bytes_warning); ADD(no_user_site); ADD(optimize); #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 /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */ #ifndef PY_NO_SHORT_FLOAT_REPR SET_SYS_FROM_STRING("float_repr_style", PyString_FromString("short")); #else SET_SYS_FROM_STRING("float_repr_style", PyString_FromString("legacy")); #endif sys_flags_cls->freeze(); auto sys_str = getStaticString("sys"); for (auto& md : sys_methods) { sys_module->giveAttr(md.ml_name, new BoxedCApiFunction(&md, NULL, sys_str)); } sys_module->giveAttrBorrowed("__displayhook__", sys_module->getattr(autoDecref(internStringMortal("displayhook")))); sys_module->giveAttr("flags", new BoxedSysFlags()); }
extern "C" BORROWED(PyObject*) PySys_GetObject(const char* name) noexcept { return sys_module->getattr(autoDecref(internStringMortal(name))); }
void setupSys() { sys_modules_dict = new BoxedDict(); PyThreadState_GET()->interp->modules = incref(sys_modules_dict); constants.push_back(sys_modules_dict); // This is ok to call here because we've already created the sys_modules_dict sys_module = createModule(autoDecref(boxString("sys"))); // sys_module is what holds on to all of the other modules: Py_INCREF(sys_module); late_constants.push_back(sys_module); sys_module->giveAttrBorrowed("modules", sys_modules_dict); BoxedList* sys_path = new BoxedList(); constants.push_back(sys_path); sys_module->giveAttrBorrowed("path", sys_path); sys_module->giveAttr("argv", new BoxedList()); sys_module->giveAttr("exc_info", new BoxedBuiltinFunctionOrMethod(BoxedCode::create((void*)sysExcInfo, BOXED_TUPLE, 0, "exc_info", exc_info_doc))); sys_module->giveAttr("exc_clear", new BoxedBuiltinFunctionOrMethod( BoxedCode::create((void*)sysExcClear, NONE, 0, "exc_clear", exc_clear_doc))); sys_module->giveAttr( "exit", new BoxedBuiltinFunctionOrMethod( BoxedCode::create((void*)sysExit, NONE, 1, false, false, "exit", exit_doc), { Py_None }, NULL)); sys_module->giveAttr("warnoptions", new BoxedList()); sys_module->giveAttrBorrowed("py3kwarning", Py_False); sys_module->giveAttr("byteorder", boxString(isLittleEndian() ? "little" : "big")); sys_module->giveAttr("platform", boxString(Py_GetPlatform())); sys_module->giveAttr("executable", boxString(Py_GetProgramFullPath())); sys_module->giveAttr( "_getframe", new BoxedFunction(BoxedCode::create((void*)sysGetFrame, UNKNOWN, 1, false, false, "_getframe"), { NULL })); sys_module->giveAttr("_current_frames", new BoxedFunction(BoxedCode::create((void*)sysCurrentFrames, UNKNOWN, 0, "_current_frames"))); sys_module->giveAttr("getdefaultencoding", new BoxedBuiltinFunctionOrMethod(BoxedCode::create( (void*)sysGetDefaultEncoding, STR, 0, "getdefaultencoding", getdefaultencoding_doc))); sys_module->giveAttr("getfilesystemencoding", new BoxedBuiltinFunctionOrMethod(BoxedCode::create( (void*)sysGetFilesystemEncoding, STR, 0, "getfilesystemencoding", getfilesystemencoding_doc))); sys_module->giveAttr("getrecursionlimit", new BoxedBuiltinFunctionOrMethod(BoxedCode::create( (void*)sysGetRecursionLimit, UNKNOWN, 0, "getrecursionlimit", getrecursionlimit_doc))); sys_module->giveAttr("dont_write_bytecode", boxBool(Py_DontWriteBytecodeFlag)); sys_module->giveAttr("prefix", boxString(Py_GetPrefix())); sys_module->giveAttr("exec_prefix", boxString(Py_GetExecPrefix())); sys_module->giveAttr("copyright", boxString("Copyright 2014-2016 Dropbox.\nAll Rights Reserved.\n\nCopyright (c) 2001-2014 " "Python Software Foundation.\nAll Rights Reserved.\n\nCopyright (c) 2000 " "BeOpen.com.\nAll Rights Reserved.\n\nCopyright (c) 1995-2001 Corporation for " "National Research Initiatives.\nAll Rights Reserved.\n\nCopyright (c) " "1991-1995 Stichting Mathematisch Centrum, Amsterdam.\nAll Rights Reserved.")); sys_module->giveAttr("version", boxString(generateVersionString())); sys_module->giveAttr("hexversion", boxInt(PY_VERSION_HEX)); sys_module->giveAttr("subversion", BoxedTuple::create({ autoDecref(boxString("Pyston")), autoDecref(boxString("")), autoDecref(boxString("")) })); sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX)); sys_module->giveAttr("maxsize", boxInt(PY_SSIZE_T_MAX)); #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 /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */ #ifndef PY_NO_SHORT_FLOAT_REPR SET_SYS_FROM_STRING("float_repr_style", PyString_FromString("short")); #else SET_SYS_FROM_STRING("float_repr_style", PyString_FromString("legacy")); #endif auto sys_str = getStaticString("sys"); for (auto& md : sys_methods) { sys_module->giveAttr(md.ml_name, new BoxedCApiFunction(&md, NULL, sys_str)); } sys_module->giveAttrBorrowed("__displayhook__", sys_module->getattr(autoDecref(internStringMortal("displayhook")))); }
Box* getSysStdout() { Box* sys_stdout = sys_module->getattr(internStringMortal("stdout")); RELEASE_ASSERT(sys_stdout, "lost sys.stdout??"); return sys_stdout; }
void setupSys() { sys_modules_dict = new BoxedDict(); gc::registerPermanentRoot(sys_modules_dict); // This is ok to call here because we've already created the sys_modules_dict sys_module = createModule("sys"); sys_module->giveAttr("modules", sys_modules_dict); BoxedList* sys_path = new BoxedList(); sys_module->giveAttr("path", sys_path); sys_module->giveAttr("argv", new BoxedList()); sys_module->giveAttr("stdout", new BoxedFile(stdout, "<stdout>", "w")); sys_module->giveAttr("stdin", new BoxedFile(stdin, "<stdin>", "r")); sys_module->giveAttr("stderr", new BoxedFile(stderr, "<stderr>", "w")); sys_module->giveAttr("__stdout__", sys_module->getattr(internStringMortal("stdout"))); sys_module->giveAttr("__stdin__", sys_module->getattr(internStringMortal("stdin"))); sys_module->giveAttr("__stderr__", sys_module->getattr(internStringMortal("stderr"))); sys_module->giveAttr( "exc_info", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)sysExcInfo, BOXED_TUPLE, 0), "exc_info")); sys_module->giveAttr("exc_clear", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)sysExcClear, NONE, 0), "exc_clear")); sys_module->giveAttr("exit", new BoxedBuiltinFunctionOrMethod( boxRTFunction((void*)sysExit, NONE, 1, 1, false, false), "exit", { None })); sys_module->giveAttr("warnoptions", new BoxedList()); sys_module->giveAttr("py3kwarning", False); sys_module->giveAttr("byteorder", boxString(isLittleEndian() ? "little" : "big")); sys_module->giveAttr("platform", boxString(Py_GetPlatform())); sys_module->giveAttr("executable", boxString(Py_GetProgramFullPath())); sys_module->giveAttr("_getframe", new BoxedFunction(boxRTFunction((void*)sysGetFrame, UNKNOWN, 1, 1, false, false), { NULL })); sys_module->giveAttr( "getdefaultencoding", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)sysGetDefaultEncoding, STR, 0), "getdefaultencoding")); sys_module->giveAttr("getfilesystemencoding", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)sysGetFilesystemEncoding, STR, 0), "getfilesystemencoding")); sys_module->giveAttr( "getrecursionlimit", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)sysGetRecursionLimit, UNKNOWN, 0), "getrecursionlimit")); sys_module->giveAttr("meta_path", new BoxedList()); sys_module->giveAttr("path_hooks", new BoxedList()); sys_module->giveAttr("path_importer_cache", new BoxedDict()); // As we don't support compile() etc yet force 'dont_write_bytecode' to true. sys_module->giveAttr("dont_write_bytecode", True); sys_module->giveAttr("prefix", boxString(Py_GetPrefix())); sys_module->giveAttr("exec_prefix", boxString(Py_GetExecPrefix())); sys_module->giveAttr("copyright", boxString("Copyright 2014-2015 Dropbox.\nAll Rights Reserved.\n\nCopyright (c) 2001-2014 " "Python Software Foundation.\nAll Rights Reserved.\n\nCopyright (c) 2000 " "BeOpen.com.\nAll Rights Reserved.\n\nCopyright (c) 1995-2001 Corporation for " "National Research Initiatives.\nAll Rights Reserved.\n\nCopyright (c) " "1991-1995 Stichting Mathematisch Centrum, Amsterdam.\nAll Rights Reserved.")); sys_module->giveAttr("version", boxString(generateVersionString())); sys_module->giveAttr("hexversion", boxInt(PY_VERSION_HEX)); // TODO: this should be a "sys.version_info" object, not just a tuple (ie can access fields by name) sys_module->giveAttr("version_info", BoxedTuple::create({ boxInt(PYTHON_VERSION_MAJOR), boxInt(PYTHON_VERSION_MINOR), boxInt(PYTHON_VERSION_MICRO), boxString("beta"), boxInt(0) })); sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX)); sys_module->giveAttr("maxsize", boxInt(PY_SSIZE_T_MAX)); sys_flags_cls = new (0) BoxedHeapClass(object_cls, BoxedSysFlags::gcHandler, 0, 0, sizeof(BoxedSysFlags), false, static_cast<BoxedString*>(boxString("flags"))); sys_flags_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)BoxedSysFlags::__new__, UNKNOWN, 1, 0, true, true))); #define ADD(name) \ sys_flags_cls->giveAttr(STRINGIFY(name), \ new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedSysFlags, name))) ADD(division_warning); ADD(bytes_warning); ADD(no_user_site); ADD(optimize); #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->freeze(); for (auto& md : sys_methods) { sys_module->giveAttr(md.ml_name, new BoxedCApiFunction(&md, sys_module)); } sys_module->giveAttr("__displayhook__", sys_module->getattr(internStringMortal("displayhook"))); sys_module->giveAttr("flags", new BoxedSysFlags()); }
void addToSysArgv(const char* str) { Box* sys_argv = sys_module->getattr(internStringMortal("argv")); assert(sys_argv); assert(sys_argv->cls == list_cls); listAppendInternal(sys_argv, boxString(str)); }
extern "C" PyObject* PySys_GetObject(const char* name) noexcept { return sys_module->getattr(internStringMortal(name)); }