From c12ecf3935fd4f86a07e3c41b3739bc55ef3f510 Mon Sep 17 00:00:00 2001 From: Arman Farhangi Date: Thu, 14 Mar 2024 15:10:25 -0700 Subject: [PATCH 1/9] Add SafeCloseable wrapper --- py/server/deephaven/jcompat.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/py/server/deephaven/jcompat.py b/py/server/deephaven/jcompat.py index a4fb34c2495..846fb081858 100644 --- a/py/server/deephaven/jcompat.py +++ b/py/server/deephaven/jcompat.py @@ -304,3 +304,24 @@ def _j_array_to_series(dtype: DType, j_array: jpy.JType, conv_null: bool) -> pd. s = pd.Series(data=np_array, copy=False) return s + + +class SafeCloseable: + """A context manager wrapper of Java SafeCloseable to emulate Java try-with-resources.""" + def __init__(self, j_safe_closeable): + self._j_safe_closeable = j_safe_closeable + self.closed = False + + def __enter__(self): + return self + + def close(self): + if not self.closed: + self.closed = True + self._j_safe_closeable.close() + + def __exit__(self, exc_type, exc_value, traceback): + self.close() + + def __del__(self): + self.close() From fbc460935f73b4aad1ec04eda577789edffec471 Mon Sep 17 00:00:00 2001 From: Arman Farhangi Date: Thu, 14 Mar 2024 21:48:23 -0700 Subject: [PATCH 2/9] Add SafeCloseable test --- py/server/tests/test_jcompat.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/py/server/tests/test_jcompat.py b/py/server/tests/test_jcompat.py index bcea58d112c..1de8d675c95 100644 --- a/py/server/tests/test_jcompat.py +++ b/py/server/tests/test_jcompat.py @@ -5,11 +5,12 @@ import unittest from deephaven import dtypes -from deephaven.jcompat import j_function, j_lambda +from deephaven.jcompat import j_function, j_lambda, SafeCloseable from tests.testbase import BaseTestCase import jpy +_JSharedContext = jpy.get_type("io.deephaven.engine.table.SharedContext") class JCompatTestCase(BaseTestCase): def test_j_function(self): @@ -29,6 +30,12 @@ def int_to_str(v: int) -> str: r = j_func.apply(10) self.assertEqual(r, "10") + def test_safe_closeable(self): + safe_closeable = SafeCloseable(_JSharedContext.makeSharedContext()) + with safe_closeable: + pass + self.assertEqual(safe_closeable.closed, True) + if __name__ == "__main__": unittest.main() From 66fcfc8d0f80bad53eb6500836e42f7fcd4e9ae5 Mon Sep 17 00:00:00 2001 From: Arman Farhangi Date: Fri, 15 Mar 2024 08:53:33 -0700 Subject: [PATCH 3/9] Extend JObjectWrapper --- py/server/deephaven/jcompat.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/py/server/deephaven/jcompat.py b/py/server/deephaven/jcompat.py index 846fb081858..cb9733df5c4 100644 --- a/py/server/deephaven/jcompat.py +++ b/py/server/deephaven/jcompat.py @@ -12,7 +12,7 @@ import pandas as pd from deephaven import dtypes, DHError -from deephaven._wrapper import unwrap, wrap_j_object +from deephaven._wrapper import unwrap, wrap_j_object, JObjectWrapper from deephaven.dtypes import DType, _PRIMITIVE_DTYPE_NULL_MAP, _J_ARRAY_NP_TYPE_MAP _NULL_BOOLEAN_AS_BYTE = jpy.get_type("io.deephaven.util.BooleanUtils").NULL_BOOLEAN_AS_BYTE @@ -306,7 +306,7 @@ def _j_array_to_series(dtype: DType, j_array: jpy.JType, conv_null: bool) -> pd. return s -class SafeCloseable: +class SafeCloseable(JObjectWrapper): """A context manager wrapper of Java SafeCloseable to emulate Java try-with-resources.""" def __init__(self, j_safe_closeable): self._j_safe_closeable = j_safe_closeable @@ -325,3 +325,7 @@ def __exit__(self, exc_type, exc_value, traceback): def __del__(self): self.close() + + @property + def j_object(self) -> jpy.JType: + return self.j_safe_closeable From 2d5470106cb41f77f8139db85fdab6484bfa5663 Mon Sep 17 00:00:00 2001 From: Arman Farhangi Date: Fri, 15 Mar 2024 09:20:50 -0700 Subject: [PATCH 4/9] Polish --- py/server/deephaven/jcompat.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/py/server/deephaven/jcompat.py b/py/server/deephaven/jcompat.py index cb9733df5c4..0b0eb1eb30d 100644 --- a/py/server/deephaven/jcompat.py +++ b/py/server/deephaven/jcompat.py @@ -308,6 +308,9 @@ def _j_array_to_series(dtype: DType, j_array: jpy.JType, conv_null: bool) -> pd. class SafeCloseable(JObjectWrapper): """A context manager wrapper of Java SafeCloseable to emulate Java try-with-resources.""" + + j_object_type = jpy.get_type("io.deephaven.util.SafeCloseable") + def __init__(self, j_safe_closeable): self._j_safe_closeable = j_safe_closeable self.closed = False From 8bb8664df0e0508a6adaff7000a3e12764b2338f Mon Sep 17 00:00:00 2001 From: Arman Farhangi Date: Fri, 15 Mar 2024 09:37:19 -0700 Subject: [PATCH 5/9] Polish --- py/server/deephaven/jcompat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/server/deephaven/jcompat.py b/py/server/deephaven/jcompat.py index 0b0eb1eb30d..f210db10271 100644 --- a/py/server/deephaven/jcompat.py +++ b/py/server/deephaven/jcompat.py @@ -331,4 +331,4 @@ def __del__(self): @property def j_object(self) -> jpy.JType: - return self.j_safe_closeable + return self._j_safe_closeable From ae90b46d8a6c6abbac2f8c6df0f40786fd87ef15 Mon Sep 17 00:00:00 2001 From: arman-ddl <122062464+arman-ddl@users.noreply.github.com> Date: Fri, 15 Mar 2024 10:41:50 -0700 Subject: [PATCH 6/9] Apply suggestions from code review Per @chipkent. Co-authored-by: Chip Kent <5250374+chipkent@users.noreply.github.com> --- py/server/deephaven/jcompat.py | 2 +- py/server/tests/test_jcompat.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/py/server/deephaven/jcompat.py b/py/server/deephaven/jcompat.py index f210db10271..f3c912933b2 100644 --- a/py/server/deephaven/jcompat.py +++ b/py/server/deephaven/jcompat.py @@ -307,7 +307,7 @@ def _j_array_to_series(dtype: DType, j_array: jpy.JType, conv_null: bool) -> pd. class SafeCloseable(JObjectWrapper): - """A context manager wrapper of Java SafeCloseable to emulate Java try-with-resources.""" + """A context manager wrapper to allow Java SafeCloseable to be used in with statements.""" j_object_type = jpy.get_type("io.deephaven.util.SafeCloseable") diff --git a/py/server/tests/test_jcompat.py b/py/server/tests/test_jcompat.py index 1de8d675c95..8f28b431639 100644 --- a/py/server/tests/test_jcompat.py +++ b/py/server/tests/test_jcompat.py @@ -33,7 +33,7 @@ def int_to_str(v: int) -> str: def test_safe_closeable(self): safe_closeable = SafeCloseable(_JSharedContext.makeSharedContext()) with safe_closeable: - pass + self.assertEqual(safe_closeable.closed, False) self.assertEqual(safe_closeable.closed, True) From 95e599a747d9333b4f205874ee3037495ebcded9 Mon Sep 17 00:00:00 2001 From: Arman Farhangi Date: Fri, 15 Mar 2024 10:45:01 -0700 Subject: [PATCH 7/9] Document assumption --- py/server/deephaven/jcompat.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/py/server/deephaven/jcompat.py b/py/server/deephaven/jcompat.py index f3c912933b2..86d7b78d677 100644 --- a/py/server/deephaven/jcompat.py +++ b/py/server/deephaven/jcompat.py @@ -307,7 +307,8 @@ def _j_array_to_series(dtype: DType, j_array: jpy.JType, conv_null: bool) -> pd. class SafeCloseable(JObjectWrapper): - """A context manager wrapper to allow Java SafeCloseable to be used in with statements.""" + """A context manager wrapper to allow Java SafeCloseable to be used in with statements. Assumes Java + SafeCloseable has not been closed yet.""" j_object_type = jpy.get_type("io.deephaven.util.SafeCloseable") From 2b708783e90a31a08f9a3a9488eef408382c0f0a Mon Sep 17 00:00:00 2001 From: arman-ddl <122062464+arman-ddl@users.noreply.github.com> Date: Fri, 15 Mar 2024 11:25:55 -0700 Subject: [PATCH 8/9] Polish pydoc Co-authored-by: Chip Kent <5250374+chipkent@users.noreply.github.com> --- py/server/deephaven/jcompat.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/py/server/deephaven/jcompat.py b/py/server/deephaven/jcompat.py index 86d7b78d677..7ab86dd9522 100644 --- a/py/server/deephaven/jcompat.py +++ b/py/server/deephaven/jcompat.py @@ -307,8 +307,9 @@ def _j_array_to_series(dtype: DType, j_array: jpy.JType, conv_null: bool) -> pd. class SafeCloseable(JObjectWrapper): - """A context manager wrapper to allow Java SafeCloseable to be used in with statements. Assumes Java - SafeCloseable has not been closed yet.""" + """A context manager wrapper to allow Java SafeCloseable to be used in with statements. + + When constructing a new instance, the Java SafeCloseable must not be closed.""" j_object_type = jpy.get_type("io.deephaven.util.SafeCloseable") From 67421f46fa39273dc3165dd11005a6ac423570ea Mon Sep 17 00:00:00 2001 From: Arman Farhangi Date: Fri, 15 Mar 2024 12:21:26 -0700 Subject: [PATCH 9/9] Change SafeCloseable to AutoCloseable --- py/server/deephaven/jcompat.py | 16 ++++++++-------- py/server/tests/test_jcompat.py | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/py/server/deephaven/jcompat.py b/py/server/deephaven/jcompat.py index 7ab86dd9522..46cb3d79a3a 100644 --- a/py/server/deephaven/jcompat.py +++ b/py/server/deephaven/jcompat.py @@ -306,15 +306,15 @@ def _j_array_to_series(dtype: DType, j_array: jpy.JType, conv_null: bool) -> pd. return s -class SafeCloseable(JObjectWrapper): - """A context manager wrapper to allow Java SafeCloseable to be used in with statements. +class AutoCloseable(JObjectWrapper): + """A context manager wrapper to allow Java AutoCloseable to be used in with statements. - When constructing a new instance, the Java SafeCloseable must not be closed.""" + When constructing a new instance, the Java AutoCloseable must not be closed.""" - j_object_type = jpy.get_type("io.deephaven.util.SafeCloseable") + j_object_type = jpy.get_type("java.lang.AutoCloseable") - def __init__(self, j_safe_closeable): - self._j_safe_closeable = j_safe_closeable + def __init__(self, j_auto_closeable): + self._j_auto_closeable = j_auto_closeable self.closed = False def __enter__(self): @@ -323,7 +323,7 @@ def __enter__(self): def close(self): if not self.closed: self.closed = True - self._j_safe_closeable.close() + self._j_auto_closeable.close() def __exit__(self, exc_type, exc_value, traceback): self.close() @@ -333,4 +333,4 @@ def __del__(self): @property def j_object(self) -> jpy.JType: - return self._j_safe_closeable + return self._j_auto_closeable diff --git a/py/server/tests/test_jcompat.py b/py/server/tests/test_jcompat.py index 8f28b431639..40241b73da2 100644 --- a/py/server/tests/test_jcompat.py +++ b/py/server/tests/test_jcompat.py @@ -5,7 +5,7 @@ import unittest from deephaven import dtypes -from deephaven.jcompat import j_function, j_lambda, SafeCloseable +from deephaven.jcompat import j_function, j_lambda, AutoCloseable from tests.testbase import BaseTestCase import jpy @@ -30,11 +30,11 @@ def int_to_str(v: int) -> str: r = j_func.apply(10) self.assertEqual(r, "10") - def test_safe_closeable(self): - safe_closeable = SafeCloseable(_JSharedContext.makeSharedContext()) - with safe_closeable: - self.assertEqual(safe_closeable.closed, False) - self.assertEqual(safe_closeable.closed, True) + def test_auto_closeable(self): + auto_closeable = AutoCloseable(_JSharedContext.makeSharedContext()) + with auto_closeable: + self.assertEqual(auto_closeable.closed, False) + self.assertEqual(auto_closeable.closed, True) if __name__ == "__main__":