Kaydet (Commit) 1ef876cd authored tarafından Benjamin Peterson's avatar Benjamin Peterson

evaluate positional defaults before keyword-only defaults (closes #16967)

üst 34a2a87d
...@@ -493,14 +493,15 @@ case the parameter's default value is substituted. If a parameter has a default ...@@ -493,14 +493,15 @@ case the parameter's default value is substituted. If a parameter has a default
value, all following parameters up until the "``*``" must also have a default value, all following parameters up until the "``*``" must also have a default
value --- this is a syntactic restriction that is not expressed by the grammar. value --- this is a syntactic restriction that is not expressed by the grammar.
**Default parameter values are evaluated when the function definition is **Default parameter values are evaluated from left to right when the function
executed.** This means that the expression is evaluated once, when the function definition is executed.** This means that the expression is evaluated once, when
is defined, and that the same "pre-computed" value is used for each call. This the function is defined, and that the same "pre-computed" value is used for each
is especially important to understand when a default parameter is a mutable call. This is especially important to understand when a default parameter is a
object, such as a list or a dictionary: if the function modifies the object mutable object, such as a list or a dictionary: if the function modifies the
(e.g. by appending an item to a list), the default value is in effect modified. object (e.g. by appending an item to a list), the default value is in effect
This is generally not what was intended. A way around this is to use ``None`` modified. This is generally not what was intended. A way around this is to use
as the default, and explicitly test for it in the body of the function, e.g.:: ``None`` as the default, and explicitly test for it in the body of the function,
e.g.::
def whats_on_the_telly(penguin=None): def whats_on_the_telly(penguin=None):
if penguin is None: if penguin is None:
......
...@@ -396,13 +396,15 @@ Known values: ...@@ -396,13 +396,15 @@ Known values:
3210 (added size modulo 2**32 to the pyc header) 3210 (added size modulo 2**32 to the pyc header)
Python 3.3a1 3220 (changed PEP 380 implementation) Python 3.3a1 3220 (changed PEP 380 implementation)
Python 3.3a4 3230 (revert changes to implicit __class__ closure) Python 3.3a4 3230 (revert changes to implicit __class__ closure)
Python 3.4a1 3240 (evaluate positional default arguments before
keyword-only defaults)
MAGIC must change whenever the bytecode emitted by the compiler may no MAGIC must change whenever the bytecode emitted by the compiler may no
longer be understood by older implementations of the eval loop (usually longer be understood by older implementations of the eval loop (usually
due to the addition of new opcodes). due to the addition of new opcodes).
""" """
_RAW_MAGIC_NUMBER = 3230 | ord('\r') << 16 | ord('\n') << 24 _RAW_MAGIC_NUMBER = 3240 | ord('\r') << 16 | ord('\n') << 24
_MAGIC_BYTES = bytes(_RAW_MAGIC_NUMBER >> n & 0xff for n in range(0, 25, 8)) _MAGIC_BYTES = bytes(_RAW_MAGIC_NUMBER >> n & 0xff for n in range(0, 25, 8))
_PYCACHE = '__pycache__' _PYCACHE = '__pycache__'
......
...@@ -176,6 +176,14 @@ class KeywordOnlyArgTestCase(unittest.TestCase): ...@@ -176,6 +176,14 @@ class KeywordOnlyArgTestCase(unittest.TestCase):
return __a return __a
self.assertEqual(X().f(), 42) self.assertEqual(X().f(), 42)
def test_default_evaluation_order(self):
# See issue 16967
a = 42
with self.assertRaises(NameError) as err:
def f(v=a, x=b, *, y=c, z=d):
pass
self.assertEqual(str(err.exception), "global name 'b' is not defined")
def test_main(): def test_main():
run_unittest(KeywordOnlyArgTestCase) run_unittest(KeywordOnlyArgTestCase)
......
...@@ -10,6 +10,9 @@ What's New in Python 3.4.0 Alpha 1? ...@@ -10,6 +10,9 @@ What's New in Python 3.4.0 Alpha 1?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #16967: In function definition, evaluate positional defaults before
keyword-only defaults.
- Issue #17173: Remove uses of locale-dependent C functions (isalpha() etc.) - Issue #17173: Remove uses of locale-dependent C functions (isalpha() etc.)
in the interpreter. in the interpreter.
......
...@@ -2901,23 +2901,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) ...@@ -2901,23 +2901,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
} }
/* XXX Maybe this should be a separate opcode? */ /* XXX Maybe this should be a separate opcode? */
if (posdefaults > 0) {
PyObject *defs = PyTuple_New(posdefaults);
if (defs == NULL) {
Py_DECREF(func);
goto error;
}
while (--posdefaults >= 0)
PyTuple_SET_ITEM(defs, posdefaults, POP());
if (PyFunction_SetDefaults(func, defs) != 0) {
/* Can't happen unless
PyFunction_SetDefaults changes. */
Py_DECREF(defs);
Py_DECREF(func);
goto error;
}
Py_DECREF(defs);
}
if (kwdefaults > 0) { if (kwdefaults > 0) {
PyObject *defs = PyDict_New(); PyObject *defs = PyDict_New();
if (defs == NULL) { if (defs == NULL) {
...@@ -2945,6 +2928,23 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) ...@@ -2945,6 +2928,23 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
} }
Py_DECREF(defs); Py_DECREF(defs);
} }
if (posdefaults > 0) {
PyObject *defs = PyTuple_New(posdefaults);
if (defs == NULL) {
Py_DECREF(func);
goto error;
}
while (--posdefaults >= 0)
PyTuple_SET_ITEM(defs, posdefaults, POP());
if (PyFunction_SetDefaults(func, defs) != 0) {
/* Can't happen unless
PyFunction_SetDefaults changes. */
Py_DECREF(defs);
Py_DECREF(func);
goto error;
}
Py_DECREF(defs);
}
PUSH(func); PUSH(func);
DISPATCH(); DISPATCH();
} }
......
...@@ -1565,6 +1565,8 @@ compiler_function(struct compiler *c, stmt_ty s) ...@@ -1565,6 +1565,8 @@ compiler_function(struct compiler *c, stmt_ty s)
if (!compiler_decorators(c, decos)) if (!compiler_decorators(c, decos))
return 0; return 0;
if (args->defaults)
VISIT_SEQ(c, expr, args->defaults);
if (args->kwonlyargs) { if (args->kwonlyargs) {
int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs, int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs,
args->kw_defaults); args->kw_defaults);
...@@ -1572,8 +1574,6 @@ compiler_function(struct compiler *c, stmt_ty s) ...@@ -1572,8 +1574,6 @@ compiler_function(struct compiler *c, stmt_ty s)
return 0; return 0;
kw_default_count = res; kw_default_count = res;
} }
if (args->defaults)
VISIT_SEQ(c, expr, args->defaults);
num_annotations = compiler_visit_annotations(c, args, returns); num_annotations = compiler_visit_annotations(c, args, returns);
if (num_annotations < 0) if (num_annotations < 0)
return 0; return 0;
......
This diff is collapsed.
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