Skip to content

Commit 6416dc9

Browse files
committed
Optimization: avoid holding frame reference when locals == globals
1 parent 387afb3 commit 6416dc9

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

marshmallow_dataclass/__init__.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class User:
3737
import collections.abc
3838
import dataclasses
3939
import inspect
40+
import sys
4041
import threading
4142
import types
4243
import warnings
@@ -208,9 +209,24 @@ def add_schema(_cls=None, base_schema=None, cls_frame=None):
208209
"""
209210

210211
def decorator(clazz: Type[_U]) -> Type[_U]:
212+
cls_frame_ = cls_frame
213+
if cls_frame is not None:
214+
cls_globals = getattr(sys.modules.get(clazz.__module__), "__dict__", None)
215+
if cls_frame.f_locals is cls_globals:
216+
# Memory optimization:
217+
# If the caller's locals are the same as the class
218+
# module globals, we don't need the locals. (This is
219+
# typically the case for dataclasses defined at the
220+
# module top-level.) (Typing.get_type_hints() knows
221+
# how to check the class module globals on its own.)
222+
# Not holding a reference to the frame in our our lazy
223+
# class attribute which is a significant win,
224+
# memory-wise.
225+
cls_frame_ = None
226+
211227
# noinspection PyTypeHints
212228
clazz.Schema = lazy_class_attribute( # type: ignore
213-
partial(class_schema, clazz, base_schema, cls_frame),
229+
partial(class_schema, clazz, base_schema, cls_frame_),
214230
"Schema",
215231
clazz.__name__,
216232
)

0 commit comments

Comments
 (0)