Skip to content

Commit 10a72b7

Browse files
committed
Additional speedup (unsure about locals)
This I'm a little less sure of. I believe this doesn't modify global namespace, but put this in a separate commit since it changes the strategy. If OK, speed up versus previous commit, is 1.09, bringing total speedup to 1.37 vs main.
1 parent e7c42bd commit 10a72b7

File tree

1 file changed

+10
-13
lines changed

1 file changed

+10
-13
lines changed

Lib/dataclasses.py

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -466,19 +466,16 @@ def _create_fn_def(name, args, body, *, locals=None, return_type=MISSING):
466466
return (name, txt, locals)
467467

468468
def _exec_fn_defs(fn_defs, globals=None):
469-
# Free variables in exec are resolved in the global namespace.
470-
# The global namespace we have is user-provided, so we can't modify it for
471-
# our purposes. So we put the things we need into locals and introduce a
472-
# scope to allow the function we're creating to close over them.
473-
locals_dict = {k: v for _, _, locals_ in fn_defs
474-
for k, v in locals_.items()}
475-
local_vars = ', '.join(locals_dict.keys())
476-
fn_names = ", ".join(name for name, _, _ in fn_defs)
477-
txt = "\n".join(f" {txt}" for _, txt, _ in fn_defs)
478-
txt = f"def __create_fn__({local_vars}):\n{txt}\n return {fn_names}"
479-
ns = {}
480-
exec(txt, globals, ns)
481-
return ns['__create_fn__'](**locals_dict)
469+
def inner_executor():
470+
txt = "\n".join(txt for _, txt, _ in fn_defs)
471+
locals_dict = {k: v for _, _, locals_ in fn_defs
472+
for k, v in locals_.items()}
473+
ns = {}
474+
ns.update(locals_dict)
475+
exec(txt, globals, ns)
476+
return (ns[name] for name, _, _ in fn_defs)
477+
return inner_executor()
478+
482479

483480
def _field_assign(frozen, name, value, self_name):
484481
# If we're a frozen class, then assign to our fields in __init__

0 commit comments

Comments
 (0)