Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1ef876c

Browse files
committed
evaluate positional defaults before keyword-only defaults (closes #16967)
1 parent 34a2a87 commit 1ef876c

7 files changed

Lines changed: 161 additions & 147 deletions

File tree

Doc/reference/compound_stmts.rst

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -493,14 +493,15 @@ case the parameter's default value is substituted. If a parameter has a default
493493
value, all following parameters up until the "``*``" must also have a default
494494
value --- this is a syntactic restriction that is not expressed by the grammar.
495495

496-
**Default parameter values are evaluated when the function definition is
497-
executed.** This means that the expression is evaluated once, when the function
498-
is defined, and that the same "pre-computed" value is used for each call. This
499-
is especially important to understand when a default parameter is a mutable
500-
object, such as a list or a dictionary: if the function modifies the object
501-
(e.g. by appending an item to a list), the default value is in effect modified.
502-
This is generally not what was intended. A way around this is to use ``None``
503-
as the default, and explicitly test for it in the body of the function, e.g.::
496+
**Default parameter values are evaluated from left to right when the function
497+
definition is executed.** This means that the expression is evaluated once, when
498+
the function is defined, and that the same "pre-computed" value is used for each
499+
call. This is especially important to understand when a default parameter is a
500+
mutable object, such as a list or a dictionary: if the function modifies the
501+
object (e.g. by appending an item to a list), the default value is in effect
502+
modified. This is generally not what was intended. A way around this is to use
503+
``None`` as the default, and explicitly test for it in the body of the function,
504+
e.g.::
504505

505506
def whats_on_the_telly(penguin=None):
506507
if penguin is None:

Lib/importlib/_bootstrap.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,13 +396,15 @@ def _call_with_frames_removed(f, *args, **kwds):
396396
3210 (added size modulo 2**32 to the pyc header)
397397
Python 3.3a1 3220 (changed PEP 380 implementation)
398398
Python 3.3a4 3230 (revert changes to implicit __class__ closure)
399+
Python 3.4a1 3240 (evaluate positional default arguments before
400+
keyword-only defaults)
399401
400402
MAGIC must change whenever the bytecode emitted by the compiler may no
401403
longer be understood by older implementations of the eval loop (usually
402404
due to the addition of new opcodes).
403405
404406
"""
405-
_RAW_MAGIC_NUMBER = 3230 | ord('\r') << 16 | ord('\n') << 24
407+
_RAW_MAGIC_NUMBER = 3240 | ord('\r') << 16 | ord('\n') << 24
406408
_MAGIC_BYTES = bytes(_RAW_MAGIC_NUMBER >> n & 0xff for n in range(0, 25, 8))
407409

408410
_PYCACHE = '__pycache__'

Lib/test/test_keywordonlyarg.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@ def f(self, *, __a=42):
176176
return __a
177177
self.assertEqual(X().f(), 42)
178178

179+
def test_default_evaluation_order(self):
180+
# See issue 16967
181+
a = 42
182+
with self.assertRaises(NameError) as err:
183+
def f(v=a, x=b, *, y=c, z=d):
184+
pass
185+
self.assertEqual(str(err.exception), "global name 'b' is not defined")
186+
179187
def test_main():
180188
run_unittest(KeywordOnlyArgTestCase)
181189

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ What's New in Python 3.4.0 Alpha 1?
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #16967: In function definition, evaluate positional defaults before
14+
keyword-only defaults.
15+
1316
- Issue #17173: Remove uses of locale-dependent C functions (isalpha() etc.)
1417
in the interpreter.
1518

Python/ceval.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2901,23 +2901,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
29012901
}
29022902

29032903
/* XXX Maybe this should be a separate opcode? */
2904-
if (posdefaults > 0) {
2905-
PyObject *defs = PyTuple_New(posdefaults);
2906-
if (defs == NULL) {
2907-
Py_DECREF(func);
2908-
goto error;
2909-
}
2910-
while (--posdefaults >= 0)
2911-
PyTuple_SET_ITEM(defs, posdefaults, POP());
2912-
if (PyFunction_SetDefaults(func, defs) != 0) {
2913-
/* Can't happen unless
2914-
PyFunction_SetDefaults changes. */
2915-
Py_DECREF(defs);
2916-
Py_DECREF(func);
2917-
goto error;
2918-
}
2919-
Py_DECREF(defs);
2920-
}
29212904
if (kwdefaults > 0) {
29222905
PyObject *defs = PyDict_New();
29232906
if (defs == NULL) {
@@ -2945,6 +2928,23 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
29452928
}
29462929
Py_DECREF(defs);
29472930
}
2931+
if (posdefaults > 0) {
2932+
PyObject *defs = PyTuple_New(posdefaults);
2933+
if (defs == NULL) {
2934+
Py_DECREF(func);
2935+
goto error;
2936+
}
2937+
while (--posdefaults >= 0)
2938+
PyTuple_SET_ITEM(defs, posdefaults, POP());
2939+
if (PyFunction_SetDefaults(func, defs) != 0) {
2940+
/* Can't happen unless
2941+
PyFunction_SetDefaults changes. */
2942+
Py_DECREF(defs);
2943+
Py_DECREF(func);
2944+
goto error;
2945+
}
2946+
Py_DECREF(defs);
2947+
}
29482948
PUSH(func);
29492949
DISPATCH();
29502950
}

Python/compile.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1565,15 +1565,15 @@ compiler_function(struct compiler *c, stmt_ty s)
15651565

15661566
if (!compiler_decorators(c, decos))
15671567
return 0;
1568+
if (args->defaults)
1569+
VISIT_SEQ(c, expr, args->defaults);
15681570
if (args->kwonlyargs) {
15691571
int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs,
15701572
args->kw_defaults);
15711573
if (res < 0)
15721574
return 0;
15731575
kw_default_count = res;
15741576
}
1575-
if (args->defaults)
1576-
VISIT_SEQ(c, expr, args->defaults);
15771577
num_annotations = compiler_visit_annotations(c, args, returns);
15781578
if (num_annotations < 0)
15791579
return 0;

0 commit comments

Comments
 (0)