aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Coghlan <ncoghlan@gmail.com>2017-12-03 11:12:20 +1000
committerGitHub <noreply@github.com>2017-12-03 11:12:20 +1000
commit078f1814f1a4413a2a0fdb8cf4490ee0fc98ef34 (patch)
tree204192eaa105d79d354dbede16b5474dc9cdc4ee /Objects/codeobject.c
parentbpo-31589 : Build PDF using xelatex for better UTF8 support. (#3940) (diff)
downloadcpython-078f1814f1a4413a2a0fdb8cf4490ee0fc98ef34.tar.gz
cpython-078f1814f1a4413a2a0fdb8cf4490ee0fc98ef34.tar.bz2
cpython-078f1814f1a4413a2a0fdb8cf4490ee0fc98ef34.zip
bpo-32176: Set CO_NOFREE in the code object constructor (GH-4675)
Previously, CO_NOFREE was set in the compiler, which meant it could end up being set incorrectly when code objects were created directly. Setting it in the constructor based on freevars and cellvars ensures it is always accurate, regardless of how the code object is defined.
Diffstat (limited to 'Objects/codeobject.c')
-rw-r--r--Objects/codeobject.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index f312f338a9b..0509b8e6400 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -124,12 +124,20 @@ PyCode_New(int argcount, int kwonlyargcount,
if (PyUnicode_READY(filename) < 0)
return NULL;
- n_cellvars = PyTuple_GET_SIZE(cellvars);
intern_strings(names);
intern_strings(varnames);
intern_strings(freevars);
intern_strings(cellvars);
intern_string_constants(consts);
+
+ /* Check for any inner or outer closure references */
+ n_cellvars = PyTuple_GET_SIZE(cellvars);
+ if (!n_cellvars && !PyTuple_GET_SIZE(freevars)) {
+ flags |= CO_NOFREE;
+ } else {
+ flags &= ~CO_NOFREE;
+ }
+
/* Create mapping between cells and arguments if needed. */
if (n_cellvars) {
Py_ssize_t total_args = argcount + kwonlyargcount +