From 9e61991c7ac0c61066486204fe94936a1ff4e186 Mon Sep 17 00:00:00 2001 From: Elliot Ford Date: Sun, 12 Feb 2023 00:08:39 +0000 Subject: [PATCH 1/9] fixes #507 -- Fix GitHub workflow badge (#508) See the linked GitHub issue from the previous version of the badge: https://github.com/badges/shields/issues/8671 In summary, this badge was changed in a breaking fashion such that the badge was just linking to the github issue rather than showing the data. Updating the url resolves this. I also updated to using py4j as the GitHub user. --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 087261db..fe8f159a 100644 --- a/README.rst +++ b/README.rst @@ -30,8 +30,8 @@ documentation fixes. Please visit the `contributing guide `_ for more information. -.. image:: https://img.shields.io/github/workflow/status/bartdag/py4j/test.svg - :target: https://github.com/bartdag/py4j/actions/workflows/test.yml +.. image:: https://img.shields.io/github/actions/workflow/status/py4j/py4j/test.yml.svg + :target: https://github.com/py4j/py4j/actions/workflows/test.yml .. image:: https://img.shields.io/pypi/l/py4j.svg From 262eb1a0bc5f0b08f867c42f9cf45bd18a69d899 Mon Sep 17 00:00:00 2001 From: Hyukjin Kwon Date: Mon, 11 Mar 2024 15:14:00 +0900 Subject: [PATCH 2/9] Upgrade Sphinx requirement for documentation build (#535) This PR proposes to upgrade Sphinx version to fix up the documentation build. It fails as below: ``` Run cd py4j-web && make clean html && cd .. rm -rf _build/* sphinx-build -b html -d _build/doctrees "-W" . _build/html Running Sphinx v4.5.0 Sphinx version error: The sphinxcontrib.applehelp extension used by this project needs at least Sphinx v5.0; it therefore cannot be built with this version. make: *** [Makefile:33: html] Error 2 mv: cannot stat 'py4j-web/_build/html': No such file or directory Error: Process completed with exit code 1. ``` for now, see also https://github.com/py4j/py4j/actions/runs/8228399854/job/22497777089?pr=519 --- py4j-web/requirements-doc.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4j-web/requirements-doc.txt b/py4j-web/requirements-doc.txt index f15077eb..3e8069e4 100644 --- a/py4j-web/requirements-doc.txt +++ b/py4j-web/requirements-doc.txt @@ -1 +1 @@ -Sphinx >=4.4,<5.0 +Sphinx >5.0,<6.0 From 8890486730e5e93e68a86f5349562dc2f7c21ace Mon Sep 17 00:00:00 2001 From: Hyukjin Kwon Date: Mon, 11 Mar 2024 15:33:18 +0900 Subject: [PATCH 3/9] Drop EOL Python versions, and add Python 3.11 support (#519) https://endoflife.date/python Python versions up to 3.7 are all EOL. This PR proposes to drop all of EOL versions, and updates its CI. --- .github/workflows/test.yml | 10 ++++------ CONTRIBUTING.rst | 2 +- py4j-python/setup.py | 7 +------ py4j-python/src/py4j/tests/java_gateway_test.py | 1 + py4j-web/contributing.rst | 2 +- py4j-web/download.rst | 3 +-- py4j-web/install.rst | 4 ++-- setup.py | 11 ++++------- 8 files changed, 15 insertions(+), 25 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1163673d..61722ae9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,19 +12,17 @@ jobs: test: runs-on: '${{ matrix.os }}' strategy: + fail-fast: false matrix: - os: [ ubuntu-18.04 ] + os: [ ubuntu-22.04 ] java-version: [ 8 ] - python-version: [ '2.7', '3.5', '3.6', '3.7', '3.8', '3.9', '3.10' ] + python-version: [ '3.9', '3.11' ] include: - os: windows-2019 java-version: 17 python-version: '3.10' - - os: ubuntu-18.04 + - os: ubuntu-22.04 java-version: 11 - python-version: '2.7' - - os: ubuntu-18.04 - java-version: 17 python-version: '3.8' name: Py ${{ matrix.python-version }}, Java ${{ matrix.java-version }}, ${{ matrix.os }} steps: diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index ca56fef5..aa3c4711 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -61,7 +61,7 @@ We follow pep8 rather stricly: 3. Line length is 80 4. Code must pass the default flake8 (version 2.5) tests (pep8 + pyflakes) -Code must be compatible with Python 2.7 and from 3.4 to the newest released +Code must be compatible with Python 3.8 to the newest released version of Python. If external libraries must be used, they should be wrapped in a mechanism that diff --git a/py4j-python/setup.py b/py4j-python/setup.py index 68c05303..eeabf340 100644 --- a/py4j-python/setup.py +++ b/py4j-python/setup.py @@ -44,15 +44,10 @@ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.4", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Programming Language :: Java", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Object Brokering", diff --git a/py4j-python/src/py4j/tests/java_gateway_test.py b/py4j-python/src/py4j/tests/java_gateway_test.py index fb357f6f..4cca6bce 100644 --- a/py4j-python/src/py4j/tests/java_gateway_test.py +++ b/py4j-python/src/py4j/tests/java_gateway_test.py @@ -1032,6 +1032,7 @@ def testAccessSubprocess(self): self.gateway = JavaGateway.launch_gateway() self.assertTrue(self.gateway.java_process) + @unittest.skipIf(sys.platform.startswith("win"), "Flaky on Windows") def testShutdownSubprocess(self): self.gateway = JavaGateway.launch_gateway() self.assertTrue(self.gateway.java_process) diff --git a/py4j-web/contributing.rst b/py4j-web/contributing.rst index 4e1a55f1..709e4900 100644 --- a/py4j-web/contributing.rst +++ b/py4j-web/contributing.rst @@ -43,7 +43,7 @@ We follow pep8 rather strictly: 3. Line length is 80. 4. Code must pass the default flake8 tests (pep8 + pyflakes). -Code must be compatible with Python 2.7 and from 3.4 to the newest released +Code must be compatible with Python 3.8 to the newest released version of Python. If external libraries must be used, they should be wrapped in a mechanism that diff --git a/py4j-web/download.rst b/py4j-web/download.rst index cf98f5c9..03136090 100644 --- a/py4j-web/download.rst +++ b/py4j-web/download.rst @@ -32,8 +32,7 @@ Requirements Py4J requires: -* A Python interpreter. Py4J has been tested with CPython 2.7, - 3.4, 3.5, 3.6, 3.7, 3.8, 3.9 and 3.10. +* A Python interpreter. Py4J has been tested with 3.8+. * Java 7.0+. Py4J for Eclipse requires: diff --git a/py4j-web/install.rst b/py4j-web/install.rst index b11e82b6..523390a4 100644 --- a/py4j-web/install.rst +++ b/py4j-web/install.rst @@ -3,11 +3,11 @@ Installing Py4J =============== -Installing Python 2.7 or 3.4-3.10 +Installing Python 3.4-3.11 --------------------------------- Py4J is a library written in Python and Java. Currently, Py4J has been tested -with Python 2.7, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9 and 3.10. You can install Python by going to the +with Python 3.8, 3.9, 3.10 and 3.11. You can install Python by going to the `official Python download page `_. diff --git a/setup.py b/setup.py index 965b821e..e485dc8d 100644 --- a/setup.py +++ b/setup.py @@ -54,13 +54,10 @@ "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.4", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Programming Language :: Java", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Object Brokering", From 570f5a664aa5e9e1e81187724f432501bc552762 Mon Sep 17 00:00:00 2001 From: Hyukjin Kwon Date: Mon, 11 Mar 2024 15:54:34 +0900 Subject: [PATCH 4/9] Fix the build combination to use different versions of JDK and Pythons with setting timeout (#536) --- .github/workflows/test.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 61722ae9..acfe81dd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,20 +11,21 @@ on: jobs: test: runs-on: '${{ matrix.os }}' + timeout-minutes: 20 strategy: fail-fast: false matrix: os: [ ubuntu-22.04 ] java-version: [ 8 ] - python-version: [ '3.9', '3.11' ] + python-version: [ '3.9', '3.8' ] include: - os: windows-2019 - java-version: 17 + java-version: 11 python-version: '3.10' - os: ubuntu-22.04 - java-version: 11 - python-version: '3.8' - name: Py ${{ matrix.python-version }}, Java ${{ matrix.java-version }}, ${{ matrix.os }} + java-version: 17 + python-version: '3.11' + name: Python ${{ matrix.python-version }}, Java ${{ matrix.java-version }}, ${{ matrix.os }} steps: - uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # pin@v2.3.5 From 74bcb776697f8cbb207b3c0b345d07b11171e5f4 Mon Sep 17 00:00:00 2001 From: Hyukjin Kwon Date: Mon, 11 Mar 2024 19:29:18 +0900 Subject: [PATCH 5/9] Add the official Python 3.12 support (#537) This PR adds the official support of Python 3.12. --- .github/workflows/test.yml | 17 +++++++++-------- py4j-python/setup.py | 1 + .../src/py4j/tests/client_server_test.py | 10 +++++----- py4j-python/src/py4j/tests/java_gateway_test.py | 8 ++++---- py4j-web/install.rst | 4 ++-- setup.py | 1 + 6 files changed, 22 insertions(+), 19 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index acfe81dd..a27c51b1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,14 +17,20 @@ jobs: matrix: os: [ ubuntu-22.04 ] java-version: [ 8 ] - python-version: [ '3.9', '3.8' ] + python-version: [ '3.8' ] include: + - os: macos-14 + java-version: 8 + python-version: '3.12' - os: windows-2019 java-version: 11 python-version: '3.10' - os: ubuntu-22.04 java-version: 17 python-version: '3.11' + - os: ubuntu-22.04 + java-version: 21 + python-version: '3.9' name: Python ${{ matrix.python-version }}, Java ${{ matrix.java-version }}, ${{ matrix.os }} steps: - uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # pin@v2.3.5 @@ -56,12 +62,7 @@ jobs: ./gradlew clean shell: bash - - name: Enable IPV6 - if: ${{ runner.os != 'Windows' }} - run: | - echo 0 | sudo tee /proc/sys/net/ipv6/conf/all/disable_ipv6 - - - name: Run gradle tests + - name: Run Gradle tests run: | cd py4j-java ./gradlew check @@ -81,7 +82,7 @@ jobs: echo `java -version` echo $JAVA_HOME # Java TLS tests are disabled until they can be fixed (refs #441) - pytest -k "not java_tls_test." + pytest -k "not java_tls_test." -vvv test-doc: name: Documentation build diff --git a/py4j-python/setup.py b/py4j-python/setup.py index eeabf340..221b575f 100644 --- a/py4j-python/setup.py +++ b/py4j-python/setup.py @@ -48,6 +48,7 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Programming Language :: Java", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Object Brokering", diff --git a/py4j-python/src/py4j/tests/client_server_test.py b/py4j-python/src/py4j/tests/client_server_test.py index e05e675b..68959373 100644 --- a/py4j-python/src/py4j/tests/client_server_test.py +++ b/py4j-python/src/py4j/tests/client_server_test.py @@ -146,7 +146,7 @@ def testSendObjects(self): start_gc_test=True, join=False) as p: p.join() client_server.shutdown() - self.assertEquals(1000, hello.calls) + self.assertEqual(1000, hello.calls) def testCleanConnections(self): """This test intentionally create multiple connections in multiple @@ -605,9 +605,9 @@ def testMultiClientServerWithSharedJavaThread(self): self.assertNotEqual(sharedPythonThreadId0, sharedPythonThreadId1) # Check that the Python thread id does not change between # invocations - self.assertEquals(sharedPythonThreadId0, + self.assertEqual(sharedPythonThreadId0, entry0.getSharedPythonThreadId()) - self.assertEquals(sharedPythonThreadId1, + self.assertEqual(sharedPythonThreadId1, entry1.getSharedPythonThreadId()) # ## 3 Hops to Shared Java Thread @@ -648,9 +648,9 @@ def testMultiClientServer(self): # ## 0 Hops to Thread ID # Check that the two thread getters get the same thread - self.assertEquals(thisThreadId, + self.assertEqual(thisThreadId, int(threadIdGetter0.getThreadId())) - self.assertEquals(thisThreadId, + self.assertEqual(thisThreadId, int(threadIdGetter1.getThreadId())) # ## 1 Hop to Thread ID diff --git a/py4j-python/src/py4j/tests/java_gateway_test.py b/py4j-python/src/py4j/tests/java_gateway_test.py index 4cca6bce..10ccb884 100644 --- a/py4j-python/src/py4j/tests/java_gateway_test.py +++ b/py4j-python/src/py4j/tests/java_gateway_test.py @@ -364,8 +364,8 @@ def testNoneArg(self): try: ex.method2(None) ex2 = ex.method4(None) - self.assertEquals(ex2.getField1(), 3) - self.assertEquals(2, ex.method7(None)) + self.assertEqual(ex2.getField1(), 3) + self.assertEqual(2, ex.method7(None)) except Exception: print_exc() self.fail() @@ -439,11 +439,11 @@ def testSetField(self): ex = self.gateway.getNewExample() set_field(ex, "field10", 2334) - self.assertEquals(get_field(ex, "field10"), 2334) + self.assertEqual(get_field(ex, "field10"), 2334) sb = self.gateway.jvm.java.lang.StringBuffer("Hello World!") set_field(ex, "field21", sb) - self.assertEquals(get_field(ex, "field21").toString(), "Hello World!") + self.assertEqual(get_field(ex, "field21").toString(), "Hello World!") self.assertRaises(Exception, set_field, ex, "field1", 123) diff --git a/py4j-web/install.rst b/py4j-web/install.rst index 523390a4..e82f7dce 100644 --- a/py4j-web/install.rst +++ b/py4j-web/install.rst @@ -3,11 +3,11 @@ Installing Py4J =============== -Installing Python 3.4-3.11 +Installing Python 3.8-3.12 --------------------------------- Py4J is a library written in Python and Java. Currently, Py4J has been tested -with Python 3.8, 3.9, 3.10 and 3.11. You can install Python by going to the +with Python 3.8, 3.9, 3.10, 3.11 and 3.12. You can install Python by going to the `official Python download page `_. diff --git a/setup.py b/setup.py index e485dc8d..555ea398 100644 --- a/setup.py +++ b/setup.py @@ -58,6 +58,7 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Programming Language :: Java", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Object Brokering", From 218bf86f035d623396d11624658a5edf36b44c8a Mon Sep 17 00:00:00 2001 From: Srinivas Lade Date: Sun, 4 Sep 2022 15:13:10 -0400 Subject: [PATCH 6/9] Add TypeInt for Specifying Integer Type --- py4j-python/src/py4j/protocol.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/py4j-python/src/py4j/protocol.py b/py4j-python/src/py4j/protocol.py index 49d7e7ec..0d3be7cb 100644 --- a/py4j-python/src/py4j/protocol.py +++ b/py4j-python/src/py4j/protocol.py @@ -21,6 +21,8 @@ from base64 import standard_b64encode, standard_b64decode from decimal import Decimal +from enum import Enum +from typing import NamedTuple from py4j.compat import ( long, basestring, unicode, bytearray2, @@ -70,6 +72,14 @@ ITERATOR_TYPE = "g" PYTHON_PROXY_TYPE = "f" +class JavaType(Enum): + PRIMITIVE_INT = INTEGER_TYPE + PRIMITIVE_LONG = LONG_TYPE + +class TypeInt(NamedTuple): + value: int + java_type: JavaType + # Protocol END = "e" ERROR = "x" @@ -277,6 +287,8 @@ def get_command_part(parameter, python_proxy_pool=None): command_part = BOOLEAN_TYPE + smart_decode(parameter) elif isinstance(parameter, Decimal): command_part = DECIMAL_TYPE + smart_decode(parameter) + elif isinstance(parameter, TypeInt): + command_part = parameter.java_type.value + smart_decode(parameter.value) elif isinstance(parameter, int) and parameter <= JAVA_MAX_INT\ and parameter >= JAVA_MIN_INT: command_part = INTEGER_TYPE + smart_decode(parameter) From 2a32b8acfc3fde7861e919804aba92340a8efff8 Mon Sep 17 00:00:00 2001 From: Srinivas Lade Date: Fri, 14 Oct 2022 11:42:41 -0400 Subject: [PATCH 7/9] Use Old NamedTuple Version --- py4j-python/src/py4j/protocol.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/py4j-python/src/py4j/protocol.py b/py4j-python/src/py4j/protocol.py index 0d3be7cb..a25e7362 100644 --- a/py4j-python/src/py4j/protocol.py +++ b/py4j-python/src/py4j/protocol.py @@ -22,7 +22,7 @@ from decimal import Decimal from enum import Enum -from typing import NamedTuple +from collections import namedtuple from py4j.compat import ( long, basestring, unicode, bytearray2, @@ -76,9 +76,7 @@ class JavaType(Enum): PRIMITIVE_INT = INTEGER_TYPE PRIMITIVE_LONG = LONG_TYPE -class TypeInt(NamedTuple): - value: int - java_type: JavaType +TypeInt = namedtuple('TypeInt', ['value', 'java_type']) # Protocol END = "e" From a642fa573a2b2301618c62943e5b604f40d42440 Mon Sep 17 00:00:00 2001 From: Rafal Mucha Date: Mon, 18 Mar 2024 21:51:03 +0100 Subject: [PATCH 8/9] Issue-374 Add unit tests & docs --- .../java/py4j/commands/DirCommandTest.java | 4 ++-- .../test/java/py4j/examples/ExampleClass.java | 15 +++++++++++++ py4j-python/src/py4j/protocol.py | 17 +++++++-------- py4j-python/src/py4j/tests/java_dir_test.py | 1 + .../src/py4j/tests/java_gateway_test.py | 8 ++++--- py4j-web/advanced_topics.rst | 21 +++++++++++++++++++ 6 files changed, 52 insertions(+), 14 deletions(-) diff --git a/py4j-java/src/test/java/py4j/commands/DirCommandTest.java b/py4j-java/src/test/java/py4j/commands/DirCommandTest.java index c177b292..fa0d1310 100644 --- a/py4j-java/src/test/java/py4j/commands/DirCommandTest.java +++ b/py4j-java/src/test/java/py4j/commands/DirCommandTest.java @@ -69,8 +69,8 @@ public class DirCommandTest { { // Defined in ExampleClass ExampleClassMethods.addAll(Arrays.asList(new String[] { "method1", "method2", "method3", "method4", "method5", - "method6", "method7", "method8", "method9", "method10", "method11", "getList", "getField1", "setField1", - "getStringArray", "getIntArray", "callHello", "callHello2", "static_method", "getInteger", + "method6", "method7", "method8", "method9", "method10", "method11", "method12", "getList", "getField1", + "setField1", "getStringArray", "getIntArray", "callHello", "callHello2", "static_method", "getInteger", "getBrokenStream", "getStream", "sleepFirstTimeOnly" })); // Defined in Object ExampleClassMethods.addAll(Arrays diff --git a/py4j-java/src/test/java/py4j/examples/ExampleClass.java b/py4j-java/src/test/java/py4j/examples/ExampleClass.java index 933daf82..75df0ef8 100644 --- a/py4j-java/src/test/java/py4j/examples/ExampleClass.java +++ b/py4j-java/src/test/java/py4j/examples/ExampleClass.java @@ -37,6 +37,7 @@ import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; public class ExampleClass { @@ -174,6 +175,20 @@ public BigInteger method11(BigInteger bi) { return bi.add(new BigInteger("1")); } + public int method12(HashSet set) { + Object element = set.stream().findAny().get(); + if (element instanceof Long) { + return 4; + } + if (element instanceof Integer) { + return 1; + } + if (element instanceof String) { + return 2; + } + return 3; + } + @SuppressWarnings("unused") private int private_method() { return 0; diff --git a/py4j-python/src/py4j/protocol.py b/py4j-python/src/py4j/protocol.py index a25e7362..1f983d77 100644 --- a/py4j-python/src/py4j/protocol.py +++ b/py4j-python/src/py4j/protocol.py @@ -21,8 +21,6 @@ from base64 import standard_b64encode, standard_b64decode from decimal import Decimal -from enum import Enum -from collections import namedtuple from py4j.compat import ( long, basestring, unicode, bytearray2, @@ -72,11 +70,12 @@ ITERATOR_TYPE = "g" PYTHON_PROXY_TYPE = "f" -class JavaType(Enum): - PRIMITIVE_INT = INTEGER_TYPE - PRIMITIVE_LONG = LONG_TYPE - -TypeInt = namedtuple('TypeInt', ['value', 'java_type']) +class TypeHint: + """Enables users to provide a hint to the Python to Java converter specifying the accurate data type for a given value. + Essential to enforce i.e. correct number type, like Long.""" + def __init__(self, value, java_type): + self.value = value + self.java_type = java_type # Protocol END = "e" @@ -281,12 +280,12 @@ def get_command_part(parameter, python_proxy_pool=None): if parameter is None: command_part = NULL_TYPE + elif isinstance(parameter, TypeHint): + command_part = parameter.java_type + smart_decode(parameter.value) elif isinstance(parameter, bool): command_part = BOOLEAN_TYPE + smart_decode(parameter) elif isinstance(parameter, Decimal): command_part = DECIMAL_TYPE + smart_decode(parameter) - elif isinstance(parameter, TypeInt): - command_part = parameter.java_type.value + smart_decode(parameter.value) elif isinstance(parameter, int) and parameter <= JAVA_MAX_INT\ and parameter >= JAVA_MIN_INT: command_part = INTEGER_TYPE + smart_decode(parameter) diff --git a/py4j-python/src/py4j/tests/java_dir_test.py b/py4j-python/src/py4j/tests/java_dir_test.py index f8a1e0bd..77057c78 100644 --- a/py4j-python/src/py4j/tests/java_dir_test.py +++ b/py4j-python/src/py4j/tests/java_dir_test.py @@ -30,6 +30,7 @@ # overloaded "method10", "method11", + "method12", "getList", "getField1", "setField1", diff --git a/py4j-python/src/py4j/tests/java_gateway_test.py b/py4j-python/src/py4j/tests/java_gateway_test.py index 10ccb884..cb60df7c 100644 --- a/py4j-python/src/py4j/tests/java_gateway_test.py +++ b/py4j-python/src/py4j/tests/java_gateway_test.py @@ -33,8 +33,8 @@ set_default_callback_accept_timeout, GatewayConnectionGuard, get_java_class) from py4j.protocol import ( - Py4JError, Py4JJavaError, Py4JNetworkError, decode_bytearray, - encode_bytearray, escape_new_line, unescape_new_line, smart_decode) + Py4JError, Py4JJavaError, Py4JNetworkError, TypeHint, LONG_TYPE, + decode_bytearray, encode_bytearray, escape_new_line, unescape_new_line, smart_decode) SERVER_PORT = 25333 @@ -607,7 +607,7 @@ def internal(): class TypeConversionTest(unittest.TestCase): def setUp(self): self.p = start_example_app_process() - self.gateway = JavaGateway() + self.gateway = JavaGateway(auto_convert=True) def tearDown(self): safe_shutdown(self) @@ -619,6 +619,8 @@ def testLongInt(self): self.assertEqual(4, ex.method7(2147483648)) self.assertEqual(4, ex.method7(-2147483649)) self.assertEqual(4, ex.method7(long(2147483648))) + self.assertEqual(4, ex.method7(TypeHint(1, LONG_TYPE))) + self.assertEqual(4, ex.method12({TypeHint(1, LONG_TYPE)})) self.assertEqual(long(4), ex.method8(3)) self.assertEqual(4, ex.method8(3)) self.assertEqual(long(4), ex.method8(long(3))) diff --git a/py4j-web/advanced_topics.rst b/py4j-web/advanced_topics.rst index 18504bbc..41ed9b4b 100644 --- a/py4j-web/advanced_topics.rst +++ b/py4j-web/advanced_topics.rst @@ -726,6 +726,27 @@ Java methods slightly less efficient because in the worst case, Py4J needs to go through all registered converters for all parameters. This is why automatic conversion is disabled by default. +.. _explicit_conversion: + +Explicit converting Python objects to Java primitives +----------------------------------------------------- + +Sometimes, especially when ``auto_convert=True`` it is difficult to enforce correct type +passed from Python to Java. Then, ``TypeHint`` from ``py4j.protocol`` may be used. +``java_type`` argument of constructor should be one of Java types defined in ``py4j.protocol``. + +So if you have method in Java like: + +.. code-block:: java + + void method(HashSet longs) {} + +Then you can pass arguments with correct type to this method with ``TypeHint`` + +:: + + >>> set_with_longs = { TypeHint(1, LONG_TYPE), TypeHint(2, LONG_TYPE) } + >>> gateway.jvm.my.Class().method(set_with_longs) .. _py4j_exceptions: From 22fdb73621360bbe5bc1e8da1fe9ab48f41ee4ae Mon Sep 17 00:00:00 2001 From: Rafal Mucha Date: Mon, 18 Mar 2024 23:02:35 +0100 Subject: [PATCH 9/9] Debug test --- .github/workflows/test.yml | 20 +++++++++---------- .../src/py4j/tests/java_gateway_test.py | 1 + 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a27c51b1..8ddf0856 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,15 +22,15 @@ jobs: - os: macos-14 java-version: 8 python-version: '3.12' - - os: windows-2019 - java-version: 11 - python-version: '3.10' - - os: ubuntu-22.04 - java-version: 17 - python-version: '3.11' - - os: ubuntu-22.04 - java-version: 21 - python-version: '3.9' + # - os: windows-2019 + # java-version: 11 + # python-version: '3.10' + # - os: ubuntu-22.04 + # java-version: 17 + # python-version: '3.11' + # - os: ubuntu-22.04 + # java-version: 21 + # python-version: '3.9' name: Python ${{ matrix.python-version }}, Java ${{ matrix.java-version }}, ${{ matrix.os }} steps: - uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # pin@v2.3.5 @@ -82,7 +82,7 @@ jobs: echo `java -version` echo $JAVA_HOME # Java TLS tests are disabled until they can be fixed (refs #441) - pytest -k "not java_tls_test." -vvv + pytest -k "not java_tls_test." -vvv -s test-doc: name: Documentation build diff --git a/py4j-python/src/py4j/tests/java_gateway_test.py b/py4j-python/src/py4j/tests/java_gateway_test.py index cb60df7c..90800c7c 100644 --- a/py4j-python/src/py4j/tests/java_gateway_test.py +++ b/py4j-python/src/py4j/tests/java_gateway_test.py @@ -582,6 +582,7 @@ def testGCCollectNoMemoryManagement(self): enable_memory_management=False)) gc.collect() # Should have nothing in the finalizers + print(ThreadSafeFinalizer.finalizers) self.assertEqual(len(ThreadSafeFinalizer.finalizers), 0) def internal():