From 7b97b749ef6f26861a50dec0415f572d6307b710 Mon Sep 17 00:00:00 2001 From: sneakers-the-rat Date: Wed, 6 Sep 2023 19:32:33 -0700 Subject: [PATCH] monkeypatch to fix perf problems from nptyping --- nwb_linkml/src/nwb_linkml/__init__.py | 6 ++- nwb_linkml/src/nwb_linkml/models/__init__.py | 0 nwb_linkml/src/nwb_linkml/monkeypatch.py | 43 ++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 nwb_linkml/src/nwb_linkml/models/__init__.py create mode 100644 nwb_linkml/src/nwb_linkml/monkeypatch.py diff --git a/nwb_linkml/src/nwb_linkml/__init__.py b/nwb_linkml/src/nwb_linkml/__init__.py index 2ea95fc..93d0c17 100644 --- a/nwb_linkml/src/nwb_linkml/__init__.py +++ b/nwb_linkml/src/nwb_linkml/__init__.py @@ -1 +1,5 @@ -from nwb_linkml.maps import preload \ No newline at end of file +from nwb_linkml.monkeypatch import apply_patches +apply_patches() + +from nwb_linkml.maps import preload + diff --git a/nwb_linkml/src/nwb_linkml/models/__init__.py b/nwb_linkml/src/nwb_linkml/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nwb_linkml/src/nwb_linkml/monkeypatch.py b/nwb_linkml/src/nwb_linkml/monkeypatch.py new file mode 100644 index 0000000..bc58be9 --- /dev/null +++ b/nwb_linkml/src/nwb_linkml/monkeypatch.py @@ -0,0 +1,43 @@ +""" +Monkeypatches to external modules +""" + +def patch_npytyping(): + """ + npytyping makes an expensive call to inspect.stack() + that makes imports of pydantic models take ~200x longer than + they should: + + References: + - https://github.com/ramonhagenaars/nptyping/issues/110 + """ + from nptyping import ndarray + from nptyping.pandas_ import dataframe + from nptyping import recarray + from nptyping import base_meta_classes + import inspect + from types import FrameType + + # make a new __module__ methods for the affected classes + def new_module_ndarray(cls) -> str: + return cls._get_module(inspect.currentframe(), 'nptyping.ndarray') + + def new_module_recarray(cls) -> str: + return cls._get_module(inspect.currentframe(), 'nptyping.recarray') + + def new_module_dataframe(cls) -> str: + return cls._get_module(inspect.currentframe(), 'nptyping.pandas_.dataframe') + + # and a new _get_module method for the parent class + def new_get_module(cls, stack: FrameType, module: str) -> str: + return "typing" if inspect.getframeinfo(stack.f_back).function == "formatannotation" else module + + # now apply the patches + ndarray.NDArrayMeta.__module__ = property(new_module_ndarray) + recarray.RecArrayMeta.__module__ = property(new_module_recarray) + dataframe.DataFrameMeta.__module__ = property(new_module_dataframe) + base_meta_classes.SubscriptableMeta._get_module = new_get_module + + +def apply_patches(): + patch_npytyping() \ No newline at end of file