Commit 7e1ff6cb authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #560 from undingen/lxml2

Add PyErr_GetExcInfo, make __builtins__ more similar to cpython and id() output more useful
parents aada26f8 711022ba
......@@ -344,6 +344,7 @@ STDMODULE_SRCS := \
signalmodule.c \
selectmodule.c \
fcntlmodule.c \
threadmodule.c \
timemodule.c \
arraymodule.c \
zlibmodule.c \
......
......@@ -83,6 +83,10 @@ PyAPI_FUNC(void) PyErr_Clear(void) PYSTON_NOEXCEPT;
PyAPI_FUNC(void) PyErr_Fetch(PyObject **, PyObject **, PyObject **) PYSTON_NOEXCEPT;
PyAPI_FUNC(void) PyErr_Restore(PyObject *, PyObject *, PyObject *) PYSTON_NOEXCEPT;
// Pyton change: This functions are normally only available in CPython >= 3.3 and PyPy but Cython can use them.
PyAPI_FUNC(void) PyErr_GetExcInfo(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback) PYSTON_NOEXCEPT;
PyAPI_FUNC(void) PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback) PYSTON_NOEXCEPT;
#ifdef Py_DEBUG
#define _PyErr_OCCURRED() PyErr_Occurred()
#else
......
......@@ -313,6 +313,8 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
std::unique_ptr<SourceInfo> si(new SourceInfo(bm, scoping, m, m->body, fn));
bm->setattr("__doc__", si->getDocString(), NULL);
if (!bm->hasattr("__builtins__"))
bm->giveAttr("__builtins__", PyModule_GetDict(builtins_module));
CLFunction* cl_f = new CLFunction(0, 0, false, false, std::move(si));
......@@ -346,6 +348,10 @@ Box* evalOrExec(CLFunction* cl, Box* globals, Box* boxedLocals) {
// results (since sometimes eval or exec might be called on constant strings).
EffortLevel effort = EffortLevel::INTERPRETED;
Box* doc_string = cl->source->getDocString();
if (doc_string != None)
setGlobal(boxedLocals, "__doc__", doc_string);
CompiledFunction* cf = compileFunction(cl, new FunctionSpecialization(VOID), effort, NULL);
assert(cf->clfunc->versions.size());
......
......@@ -249,6 +249,11 @@ static std::string generateVersionString() {
return oss.str();
}
extern "C" const char* Py_GetVersion(void) noexcept {
static std::string version = generateVersionString();
return version.c_str();
}
static bool isLittleEndian() {
unsigned long number = 1;
char* s = (char*)&number;
......
......@@ -24,6 +24,7 @@
#include "llvm/Support/Path.h"
#include "capi/types.h"
#include "codegen/unwinding.h"
#include "core/threading.h"
#include "core/types.h"
#include "runtime/classobj.h"
......@@ -233,8 +234,14 @@ done:
extern "C" PyObject* PyObject_GetAttr(PyObject* o, PyObject* attr_name) noexcept {
if (!isSubclass(attr_name->cls, str_cls)) {
PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", Py_TYPE(attr_name)->tp_name);
return NULL;
if (PyUnicode_Check(attr_name)) {
attr_name = _PyUnicode_AsDefaultEncodedString(attr_name, NULL);
if (attr_name == NULL)
return NULL;
} else {
PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", Py_TYPE(attr_name)->tp_name);
return NULL;
}
}
try {
......@@ -958,6 +965,20 @@ extern "C" void PyErr_Clear() noexcept {
PyErr_Restore(NULL, NULL, NULL);
}
extern "C" void PyErr_GetExcInfo(PyObject** ptype, PyObject** pvalue, PyObject** ptraceback) noexcept {
ExcInfo* exc = getFrameExcInfo();
*ptype = exc->type;
*pvalue = exc->value;
*ptraceback = exc->traceback;
}
extern "C" void PyErr_SetExcInfo(PyObject* type, PyObject* value, PyObject* traceback) noexcept {
ExcInfo* exc = getFrameExcInfo();
exc->type = type;
exc->value = value;
exc->traceback = traceback;
}
extern "C" void PyErr_SetString(PyObject* exception, const char* string) noexcept {
PyErr_SetObject(exception, boxStrConstant(string));
}
......@@ -1694,6 +1715,10 @@ extern "C" void _Py_FatalError(const char* fmt, const char* function, const char
abort();
}
extern "C" PyObject* PyClassMethod_New(PyObject* callable) noexcept {
return new BoxedClassmethod(callable);
}
void setupCAPI() {
capifunc_cls->giveAttr("__repr__",
new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__repr__, UNKNOWN, 1)));
......
......@@ -4822,14 +4822,6 @@ extern "C" Box* getGlobal(Box* globals, const std::string* name) {
static StatCounter stat_builtins("getglobal_builtins");
stat_builtins.log();
if ((*name) == "__builtins__") {
if (rewriter.get()) {
RewriterVar* r_rtn = rewriter->loadConst((intptr_t)builtins_module, rewriter->getReturnDestination());
rewriter->commitReturning(r_rtn);
}
return builtins_module;
}
Box* rtn;
if (rewriter.get()) {
RewriterVar* builtins = rewriter->loadConst((intptr_t)builtins_module, Location::any());
......
......@@ -2803,6 +2803,8 @@ BoxedModule* createModule(const std::string& name, const char* fn, const char* d
module->giveAttr("__file__", boxString(fn));
d->d[b_name] = module;
if (name == "__main__")
module->giveAttr("__builtins__", builtins_module);
return module;
}
......
......@@ -21,11 +21,13 @@ set -e
set -ux
python -c 'import __future__'
python -c 'import sys; print sys.executable'
pip install bcrypt==1.1.0 python-gflags==2.0 sqlalchemy==1.0.0 Pillow==2.8.1
pip install bcrypt==1.1.0 python-gflags==2.0 sqlalchemy==1.0.0 Pillow==2.8.1 decorator oauth2client
python -c 'import bcrypt; assert bcrypt.__version__ == "1.1.0"; assert bcrypt.hashpw("password1", "$2a$12$0123456789012345678901").endswith("I1hdtg4K"); print "bcrypt seems to work"'
python -c 'import gflags; print "gflags imports"'
python -c 'import sqlalchemy; print "sqlalchemy imports"'
python -c 'from PIL import Image; print "Pillow imports"'
python -c 'import decorator; print "decorator imports"'
python -c 'import oauth2client; print "oauth2client imports"'
""".strip()
# print sh_script
......
......@@ -12,6 +12,8 @@ print __builtins__
__builtins__ = 2
print __builtins__
import builtins_getitem
print all([]), all([True]), all([False]), all([None]), all([True, False, None])
print any([]), any([True]), any([False]), any([None]), any([True, False, None])
......
# this file get's also included by the builtins.py to test that __builtins__ becomes a dict when getting imported
try:
import types
print type(__builtins__) == types.ModuleType
__builtins__["all"]
print "No exception"
except TypeError as e:
print e
......@@ -178,3 +178,24 @@ print z
"""
exec s in import_target.__dict__, {}
exec s in globals(), {}
exec "import builtins_getitem"
exec "import builtins_getitem" in {}, {}
s = "print __doc__"
g = {}
l = {}
exec s in g, l
print l
s = """
'test'
print __doc__
"""
g = {}
l = {}
exec s in g, l
print l
exec s
print __doc__
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