Commit cac97e27 authored by Robert Bradshaw's avatar Robert Bradshaw

merge

parents 17fabe5a cf8dc445
......@@ -6,6 +6,7 @@ from Symtab import BuiltinScope, StructOrUnionScope
from Cython.Utils import UtilityCode
from TypeSlots import Signature
import PyrexTypes
import Naming
builtin_function_table = [
# name, args, return, C API func, py equiv = "*"
......@@ -16,6 +17,7 @@ builtin_function_table = [
('delattr', "OO", "r", "PyObject_DelAttr"),
('dir', "O", "O", "PyObject_Dir"),
('divmod', "OO", "O", "PyNumber_Divmod"),
('exec', "OOO", "O", "__Pyx_PyRun"),
#('eval', "", "", ""),
#('execfile', "", "", ""),
#('filter', "", "", ""),
......@@ -154,6 +156,48 @@ bad:
}
""")
pyexec_utility_code = UtilityCode(
proto = """
static PyObject* __Pyx_PyRun(PyObject*, PyObject*, PyObject*);
""",
impl = """
static PyObject* __Pyx_PyRun(PyObject* o, PyObject* globals, PyObject* locals) {
PyObject* result;
PyObject* s = 0;
if (!locals && !globals) {
globals = PyModule_GetDict(%s);""" % Naming.module_cname + """
if (!globals)
goto bad;
locals = globals;
} else if (!locals) {
locals = globals;
} else if (!globals) {
globals = locals;
}
if (PyUnicode_Check(o)) {
s = PyUnicode_AsUTF8String(o);
if (!s) goto bad;
o = s;
} else if (!PyString_Check(o)) {
/* FIXME: support file objects and code objects */
PyErr_SetString(PyExc_TypeError,
"exec currently requires a string as code input.");
goto bad;
}
result = PyRun_String(
PyString_AS_STRING(o), Py_file_input, globals, locals);
Py_XDECREF(s);
return result;
bad:
Py_XDECREF(s);
return 0;
}
""")
intern_utility_code = UtilityCode(
proto = """
#if PY_MAJOR_VERSION >= 3
......@@ -273,6 +317,7 @@ Py_XDECREF(__Pyx_PyFrozenSet_Type); __Pyx_PyFrozenSet_Type = NULL;
""")
builtin_utility_code = {
'exec' : pyexec_utility_code,
'getattr3' : getattr3_utility_code,
'intern' : intern_utility_code,
'set' : py23_set_utility_code,
......
......@@ -5,6 +5,7 @@
import string, sys, os, time, copy
import Code
import Builtin
from Errors import error, warning, InternalError
import Naming
import PyrexTypes
......@@ -3088,6 +3089,45 @@ class PrintStatNode(StatNode):
self.arg_tuple.annotate(code)
class ExecStatNode(StatNode):
# exec statement
#
# args [ExprNode]
child_attrs = ["args"]
def analyse_expressions(self, env):
for i, arg in enumerate(self.args):
arg.analyse_expressions(env)
arg = arg.coerce_to_pyobject(env)
arg.release_temp(env)
self.args[i] = arg
self.temp_result = env.allocate_temp_pyobject()
env.release_temp(self.temp_result)
env.use_utility_code(Builtin.pyexec_utility_code)
self.gil_check(env)
gil_message = "Python exec statement"
def generate_execution_code(self, code):
args = []
for arg in self.args:
arg.generate_evaluation_code(code)
args.append( arg.py_result() )
args = tuple(args + ['0', '0'][:3-len(args)])
code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
(self.temp_result,) + args))
for arg in self.args:
arg.generate_disposal_code(code)
code.putln(
code.error_goto_if_null(self.temp_result, self.pos))
code.put_decref_clear(self.temp_result, py_object_type)
def annotate(self, code):
for arg in self.args:
arg.annotate(code)
class DelStatNode(StatNode):
# del statement
#
......
......@@ -903,6 +903,21 @@ def p_print_statement(s):
return Nodes.PrintStatNode(pos,
arg_tuple = arg_tuple, append_newline = not ends_with_comma)
def p_exec_statement(s):
# s.sy == 'exec'
pos = s.position()
s.next()
args = [ p_bit_expr(s) ]
if s.sy == 'in':
s.next()
args.append(p_simple_expr(s))
if s.sy == ',':
s.next()
args.append(p_simple_expr(s))
else:
error(pos, "'exec' currently requires a target mapping (globals/locals)")
return Nodes.ExecStatNode(pos, args = args)
def p_del_statement(s):
# s.sy == 'del'
pos = s.position()
......@@ -1317,6 +1332,8 @@ def p_simple_statement(s, first_statement = 0):
node = p_global_statement(s)
elif s.sy == 'print':
node = p_print_statement(s)
elif s.sy == 'exec':
node = p_exec_statement(s)
elif s.sy == 'del':
node = p_del_statement(s)
elif s.sy == 'break':
......
......@@ -20,12 +20,17 @@ the documentation.
This code was modeled on Quixote's ptl_import.
"""
import sys, os, shutil
import imp, ihooks, glob, md5
import imp, ihooks, glob
import __builtin__
import pyxbuild
from distutils.dep_util import newer
from distutils.extension import Extension
try:
import hashlib
except ImportError:
import md5 as hashlib
mod_name = "pyximport"
assert sys.hexversion >= 0x20000b1, "need Python 2.0b1 or later"
......@@ -54,7 +59,7 @@ def _load_pyrex(name, filename):
def get_distutils_extension(modname, pyxfilename):
extra = "_" + md5.md5(open(pyxfilename).read()).hexdigest()
extra = "_" + hashlib.md5(open(pyxfilename).read()).hexdigest()
# modname = modname + extra
extension_mod = handle_special_build(modname, pyxfilename)
......
__doc__ = """# no unicode string, not tested in Python3!
#>>> a
#Traceback (most recent call last):
#NameError: name 'a' is not defined
#>>> test_module_scope()
#>>> a
>>> test_dict_scope1()
2
>>> d = {}
>>> test_dict_scope2(d)
>>> print d['b']
2
>>> d1 = {}
>>> test_dict_scope3(d1, d1)
>>> print d1['b']
2
>>> d1, d2 = {}, {}
>>> test_dict_scope3(d1, d2)
>>> print d1.get('b'), d2.get('b')
None 2
>>> d1, d2 = {}, {}
>>> test_dict_scope3(d1, d2)
>>> print d1.get('b'), d2.get('b')
None 2
>>> d1, d2 = dict(a=11), dict(c=5)
>>> test_dict_scope_ref(d1, d2)
>>> print d1.get('b'), d2.get('b')
None 16
>>> d = dict(a=11, c=5)
>>> test_dict_scope_ref(d, d)
>>> print d['b']
16
>>> d = dict(seq = [1,2,3,4])
>>> add_iter = test_def(d, 'seq')
>>> list(add_iter())
[2, 3, 4, 5]
>>> # errors
>>> d1, d2 = {}, {}
>>> test_dict_scope_ref(d1, d2)
Traceback (most recent call last):
NameError: name 'a' is not defined
"""
#def test_module_scope():
# exec "a=1+1"
# return __dict__['a']
def test_dict_scope1():
cdef dict d = {}
exec "b=1+1" in d
return d['b']
def test_dict_scope2(d):
exec "b=1+1" in d
def test_dict_scope3(d1, d2):
exec "b=1+1" in d1, d2
def test_dict_scope_ref(d1, d2):
exec "b=a+c" in d1, d2
def test_def(d, varref):
exec """
def test():
for x in %s:
yield x+1
""" % varref in d
return d['test']
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