From 11d9a139716b0e3456c9a1bd626afbac97ee6a6d Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Wed, 28 Feb 2024 17:42:54 +0800 Subject: [PATCH] clib.Session: Refactor the __getitem__ special method for performance --- pygmt/clib/session.py | 48 ++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/pygmt/clib/session.py b/pygmt/clib/session.py index 5648bf00c6e..22f9533bf90 100644 --- a/pygmt/clib/session.py +++ b/pygmt/clib/session.py @@ -91,6 +91,7 @@ np.datetime64: "GMT_DATETIME", np.timedelta64: "GMT_LONG", } +GMT_ENUMS = {} # Load the GMT library outside the Session class to avoid repeated loading. _libgmt = load_libgmt() @@ -239,23 +240,41 @@ def __exit__(self, exc_type, exc_value, traceback): """ self.destroy() - def __getitem__(self, name): + def __getitem__(self, name: str) -> int: + """ + Get the value of a GMT constant. + + Parameters + ---------- + name + The name of the constant (e.g., ``"GMT_SESSION_EXTERNAL"``). + + Returns + ------- + value + Integer value of the constant. Do not rely on this value because it might + change. + """ + if name not in GMT_ENUMS: + GMT_ENUMS[name] = self.get_enum(name) + return GMT_ENUMS[name] + + def get_enum(self, name: str) -> int: """ Get the value of a GMT constant (C enum) from gmt_resources.h. - Used to set configuration values for other API calls. Wraps - ``GMT_Get_Enum``. + Used to set configuration values for other API calls. Wraps ``GMT_Get_Enum``. Parameters ---------- - name : str - The name of the constant (e.g., ``"GMT_SESSION_EXTERNAL"``) + name + The name of the constant (e.g., ``"GMT_SESSION_EXTERNAL"``). Returns ------- - constant : int - Integer value of the constant. Do not rely on this value because it - might change. + value + Integer value of the constant. Do not rely on this value because it might + change. Raises ------ @@ -266,18 +285,15 @@ def __getitem__(self, name): "GMT_Get_Enum", argtypes=[ctp.c_void_p, ctp.c_char_p], restype=ctp.c_int ) - # The C lib introduced the void API pointer to GMT_Get_Enum so that - # it's consistent with other functions. It doesn't use the pointer so - # we can pass in None (NULL pointer). We can't give it the actual - # pointer because we need to call GMT_Get_Enum when creating a new API - # session pointer (chicken-and-egg type of thing). + # The C lib introduced the void API pointer to GMT_Get_Enum so that it's + # consistent with other functions. It doesn't use the pointer so we can pass + # in None (NULL pointer). We can't give it the actual pointer because we need + # to call GMT_Get_Enum when creating a new API session pointer (chicken-and-egg + # type of thing). session = None - value = c_get_enum(session, name.encode()) - if value is None or value == -99999: raise GMTCLibError(f"Constant '{name}' doesn't exist in libgmt.") - return value def get_libgmt_func(self, name, argtypes=None, restype=None):