]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Add comment to subtle dataclass code (gh-96133)
authorShantanu <12621235+hauntsaninja@users.noreply.github.com>
Tue, 4 Oct 2022 00:30:04 +0000 (17:30 -0700)
committerGitHub <noreply@github.com>
Tue, 4 Oct 2022 00:30:04 +0000 (17:30 -0700)
In the PR that made this change, 1st1 left a "note to self: add a
comment explaining this". This comment was never added.
https://github.com/python/cpython/pull/9518/files#r280608117

I was reading this code and it wasn't obvious to me why we weren't
exec-ing directly into locals. So I got to learn something new :-)
https://docs.python.org/3/reference/executionmodel.html#interaction-with-dynamic-features

Lib/dataclasses.py

index 05d62b6257605acc9b5fff7aa52cead0edfabad6..efd83467bfa9b0b4f1cba732f4a6ec730adf8336 100644 (file)
@@ -429,6 +429,10 @@ def _create_fn(name, args, body, *, globals=None, locals=None,
     # Compute the text of the entire function.
     txt = f' def {name}({args}){return_annotation}:\n{body}'
 
+    # Free variables in exec are resolved in the global namespace.
+    # The global namespace we have is user-provided, so we can't modify it for
+    # our purposes. So we put the things we need into locals and introduce a
+    # scope to allow the function we're creating to close over them.
     local_vars = ', '.join(locals.keys())
     txt = f"def __create_fn__({local_vars}):\n{txt}\n return {name}"
     ns = {}