Commit 6caf4402 authored by Stefan Behnel's avatar Stefan Behnel

extended exec() implementation, mostly copied from Py3.1

parent 5bb27ff1
...@@ -165,32 +165,42 @@ pyexec_utility_code = UtilityCode( ...@@ -165,32 +165,42 @@ pyexec_utility_code = UtilityCode(
proto = """ proto = """
static PyObject* __Pyx_PyRun(PyObject*, PyObject*, PyObject*); static PyObject* __Pyx_PyRun(PyObject*, PyObject*, PyObject*);
""", """,
impl = """ impl = '''
static PyObject* __Pyx_PyRun(PyObject* o, PyObject* globals, PyObject* locals) { static PyObject* __Pyx_PyRun(PyObject* o, PyObject* globals, PyObject* locals) {
PyObject* result; PyObject* result;
PyObject* s = 0; PyObject* s = 0;
char *code = 0; char *code = 0;
if (!locals && !globals) { if (!globals || globals == Py_None) {
globals = PyModule_GetDict(%s);""" % Naming.module_cname + """ globals = PyModule_GetDict(%s);''' % Naming.module_cname + '''
if (!globals) if (!globals)
goto bad; goto bad;
} else if (!PyDict_Check(globals)) {
PyErr_Format(PyExc_TypeError, "exec() arg 2 must be a dict, not %.100s",
globals->ob_type->tp_name);
goto bad;
}
if (!locals || locals == Py_None) {
locals = globals; locals = globals;
} else if (!locals) {
locals = globals;
} else if (!globals) {
globals = locals;
} }
if (PyDict_GetItemString(globals, "__builtins__") == NULL) { if (PyDict_GetItemString(globals, "__builtins__") == NULL) {
PyDict_SetItemString(globals, "__builtins__", PyEval_GetBuiltins()); PyDict_SetItemString(globals, "__builtins__", PyEval_GetBuiltins());
} }
if (PyCode_Check(o)) { if (PyCode_Check(o)) {
result = PyEval_EvalCode((PyCodeObject *)o, globals, locals); if (PyCode_GetNumFree((PyCodeObject *)o) > 0) {
PyErr_SetString(PyExc_TypeError,
"code object passed to exec() may not contain free variables");
goto bad;
} }
else { result = PyEval_EvalCode((PyCodeObject *)o, globals, locals);
} else {
PyCompilerFlags cf;
cf.cf_flags = 0;
if (PyUnicode_Check(o)) { if (PyUnicode_Check(o)) {
cf.cf_flags = PyCF_SOURCE_IS_UTF8;
s = PyUnicode_AsUTF8String(o); s = PyUnicode_AsUTF8String(o);
if (!s) goto bad; if (!s) goto bad;
o = s; o = s;
...@@ -208,16 +218,20 @@ static PyObject* __Pyx_PyRun(PyObject* o, PyObject* globals, PyObject* locals) { ...@@ -208,16 +218,20 @@ static PyObject* __Pyx_PyRun(PyObject* o, PyObject* globals, PyObject* locals) {
#else #else
code = PyString_AS_STRING(o); code = PyString_AS_STRING(o);
#endif #endif
if (PyEval_MergeCompilerFlags(&cf)) {
result = PyRun_StringFlags(code, Py_file_input, globals, locals, &cf);
} else {
result = PyRun_String(code, Py_file_input, globals, locals); result = PyRun_String(code, Py_file_input, globals, locals);
} }
Py_XDECREF(s); Py_XDECREF(s);
}
return result; return result;
bad: bad:
Py_XDECREF(s); Py_XDECREF(s);
return 0; return 0;
} }
""") ''')
intern_utility_code = UtilityCode( intern_utility_code = UtilityCode(
proto = """ proto = """
......
# -*- coding: utf-8 -*-
__doc__ = u""" __doc__ = u"""
#>>> a #>>> a
#Traceback (most recent call last): #Traceback (most recent call last):
...@@ -43,6 +45,21 @@ __doc__ = u""" ...@@ -43,6 +45,21 @@ __doc__ = u"""
>>> list(add_iter()) >>> list(add_iter())
[2, 3, 4, 5] [2, 3, 4, 5]
>>> d = {}
>>> test_encoding(d, None)
>>> print(d['b'])
üöä
>>> d = {}
>>> test_encoding_unicode(d, None)
>>> print(d['b'])
üöä
>>> d = dict(a=1, c=3)
>>> test_compile(d)
>>> d['b']
4
>>> # errors >>> # errors
>>> d1, d2 = {}, {} >>> d1, d2 = {}, {}
...@@ -76,3 +93,23 @@ def test(): ...@@ -76,3 +93,23 @@ def test():
yield x+1 yield x+1
""" % varref in d """ % varref in d
return d[u'test'] return d[u'test']
import sys
def test_encoding(d1, d2):
if sys.version_info[0] >= 3:
s = "b = 'üöä'"
else:
s = "# -*- coding: utf-8 -*-" + "\n" + "b = u'üöä'"
exec s in d1, d2
def test_encoding_unicode(d1, d2):
if sys.version_info[0] >= 3:
s = u"b = 'üöä'"
else:
s = u"b = u'üöä'"
exec s in d1, d2
def test_compile(d):
c = compile(u"b = a+c", u"<string>", u"exec")
exec c in d
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