Commit f1481bdc authored by Georg Brandl's avatar Georg Brandl

Patch #1444529: the builtin compile() now accepts keyword arguments.

 (backport)
parent 4fa38599
...@@ -175,15 +175,15 @@ class C: ...@@ -175,15 +175,15 @@ class C:
\code{\var{x} > \var{y}}. \code{\var{x} > \var{y}}.
\end{funcdesc} \end{funcdesc}
\begin{funcdesc}{compile}{string, filename, kind\optional{, \begin{funcdesc}{compile}{source, filename, mode\optional{,
flags\optional{, dont_inherit}}} flags\optional{, dont_inherit}}}
Compile the \var{string} into a code object. Code objects can be Compile the \var{source} into a code object. Code objects can be
executed by an \keyword{exec} statement or evaluated by a call to executed by an \keyword{exec} statement or evaluated by a call to
\function{eval()}. The \var{filename} argument should \function{eval()}. The \var{filename} argument should
give the file from which the code was read; pass some recognizable value give the file from which the code was read; pass some recognizable value
if it wasn't read from a file (\code{'<string>'} is commonly used). if it wasn't read from a file (\code{'<string>'} is commonly used).
The \var{kind} argument specifies what kind of code must be The \var{mode} argument specifies what kind of code must be
compiled; it can be \code{'exec'} if \var{string} consists of a compiled; it can be \code{'exec'} if \var{source} consists of a
sequence of statements, \code{'eval'} if it consists of a single sequence of statements, \code{'eval'} if it consists of a single
expression, or \code{'single'} if it consists of a single expression, or \code{'single'} if it consists of a single
interactive statement (in the latter case, expression statements interactive statement (in the latter case, expression statements
...@@ -198,7 +198,7 @@ class C: ...@@ -198,7 +198,7 @@ class C:
The optional arguments \var{flags} and \var{dont_inherit} The optional arguments \var{flags} and \var{dont_inherit}
(which are new in Python 2.2) control which future statements (see (which are new in Python 2.2) control which future statements (see
\pep{236}) affect the compilation of \var{string}. If neither is \pep{236}) affect the compilation of \var{source}. If neither is
present (or both are zero) the code is compiled with those future present (or both are zero) the code is compiled with those future
statements that are in effect in the code that is calling compile. statements that are in effect in the code that is calling compile.
If the \var{flags} argument is given and \var{dont_inherit} is not If the \var{flags} argument is given and \var{dont_inherit} is not
......
...@@ -107,9 +107,12 @@ class BuiltinTest(unittest.TestCase): ...@@ -107,9 +107,12 @@ class BuiltinTest(unittest.TestCase):
__import__('sys') __import__('sys')
__import__('time') __import__('time')
__import__('string') __import__('string')
__import__(name='sys')
__import__(name='time', level=0)
self.assertRaises(ImportError, __import__, 'spamspam') self.assertRaises(ImportError, __import__, 'spamspam')
self.assertRaises(TypeError, __import__, 1, 2, 3, 4) self.assertRaises(TypeError, __import__, 1, 2, 3, 4)
self.assertRaises(ValueError, __import__, '') self.assertRaises(ValueError, __import__, '')
self.assertRaises(TypeError, __import__, 'sys', name='sys')
def test_abs(self): def test_abs(self):
# int # int
...@@ -243,15 +246,21 @@ class BuiltinTest(unittest.TestCase): ...@@ -243,15 +246,21 @@ class BuiltinTest(unittest.TestCase):
compile('print 1\n', '', 'exec') compile('print 1\n', '', 'exec')
bom = '\xef\xbb\xbf' bom = '\xef\xbb\xbf'
compile(bom + 'print 1\n', '', 'exec') compile(bom + 'print 1\n', '', 'exec')
compile(source='pass', filename='?', mode='exec')
compile(dont_inherit=0, filename='tmp', source='0', mode='eval')
compile('pass', '?', dont_inherit=1, mode='exec')
self.assertRaises(TypeError, compile) self.assertRaises(TypeError, compile)
self.assertRaises(ValueError, compile, 'print 42\n', '<string>', 'badmode') self.assertRaises(ValueError, compile, 'print 42\n', '<string>', 'badmode')
self.assertRaises(ValueError, compile, 'print 42\n', '<string>', 'single', 0xff) self.assertRaises(ValueError, compile, 'print 42\n', '<string>', 'single', 0xff)
self.assertRaises(TypeError, compile, chr(0), 'f', 'exec') self.assertRaises(TypeError, compile, chr(0), 'f', 'exec')
self.assertRaises(TypeError, compile, 'pass', '?', 'exec',
mode='eval', source='0', filename='tmp')
if have_unicode: if have_unicode:
compile(unicode('print u"\xc3\xa5"\n', 'utf8'), '', 'exec') compile(unicode('print u"\xc3\xa5"\n', 'utf8'), '', 'exec')
self.assertRaises(TypeError, compile, unichr(0), 'f', 'exec') self.assertRaises(TypeError, compile, unichr(0), 'f', 'exec')
self.assertRaises(ValueError, compile, unicode('a = 1'), 'f', 'bad') self.assertRaises(ValueError, compile, unicode('a = 1'), 'f', 'bad')
def test_delattr(self): def test_delattr(self):
import sys import sys
sys.spam = 1 sys.spam = 1
......
...@@ -12,6 +12,8 @@ What's New in Python 2.6 alpha 1? ...@@ -12,6 +12,8 @@ What's New in Python 2.6 alpha 1?
Core and builtins Core and builtins
----------------- -----------------
- Patch #1444529: the builtin compile() now accepts keyword arguments.
- Bug #1678647: write a newline after printing an exception in any - Bug #1678647: write a newline after printing an exception in any
case, even when converting the value to a string failed. case, even when converting the value to a string failed.
......
...@@ -402,7 +402,7 @@ a common type, using the same rules as used by arithmetic operations.\n\ ...@@ -402,7 +402,7 @@ a common type, using the same rules as used by arithmetic operations.\n\
If coercion is not possible, raise TypeError."); If coercion is not possible, raise TypeError.");
static PyObject * static PyObject *
builtin_compile(PyObject *self, PyObject *args) builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
{ {
char *str; char *str;
char *filename; char *filename;
...@@ -413,9 +413,12 @@ builtin_compile(PyObject *self, PyObject *args) ...@@ -413,9 +413,12 @@ builtin_compile(PyObject *self, PyObject *args)
PyCompilerFlags cf; PyCompilerFlags cf;
PyObject *result = NULL, *cmd, *tmp = NULL; PyObject *result = NULL, *cmd, *tmp = NULL;
Py_ssize_t length; Py_ssize_t length;
static char *kwlist[] = {"source", "filename", "mode", "flags",
"dont_inherit", NULL};
if (!PyArg_ParseTuple(args, "Oss|ii:compile", &cmd, &filename, if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oss|ii:compile",
&startstr, &supplied_flags, &dont_inherit)) kwlist, &cmd, &filename, &startstr,
&supplied_flags, &dont_inherit))
return NULL; return NULL;
cf.cf_flags = supplied_flags; cf.cf_flags = supplied_flags;
...@@ -2237,7 +2240,7 @@ static PyMethodDef builtin_methods[] = { ...@@ -2237,7 +2240,7 @@ static PyMethodDef builtin_methods[] = {
{"chr", builtin_chr, METH_VARARGS, chr_doc}, {"chr", builtin_chr, METH_VARARGS, chr_doc},
{"cmp", builtin_cmp, METH_VARARGS, cmp_doc}, {"cmp", builtin_cmp, METH_VARARGS, cmp_doc},
{"coerce", builtin_coerce, METH_VARARGS, coerce_doc}, {"coerce", builtin_coerce, METH_VARARGS, coerce_doc},
{"compile", builtin_compile, METH_VARARGS, compile_doc}, {"compile", (PyCFunction)builtin_compile, METH_VARARGS | METH_KEYWORDS, compile_doc},
{"delattr", builtin_delattr, METH_VARARGS, delattr_doc}, {"delattr", builtin_delattr, METH_VARARGS, delattr_doc},
{"dir", builtin_dir, METH_VARARGS, dir_doc}, {"dir", builtin_dir, METH_VARARGS, dir_doc},
{"divmod", builtin_divmod, METH_VARARGS, divmod_doc}, {"divmod", builtin_divmod, METH_VARARGS, divmod_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