From 4d864a6badea49bce0b00d27ab14bb14394255a3 Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sat, 9 Nov 2024 17:15:16 -0800 Subject: [PATCH 01/43] Update release --- .azure/release.yml | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/.azure/release.yml b/.azure/release.yml index b43d59fda..4cf2280a6 100644 --- a/.azure/release.yml +++ b/.azure/release.yml @@ -35,15 +35,20 @@ stages: # plat: manylinux2014_aarch64 # image: quay.io/pypa/manylinux2014_aarch64 # python.architecture: aarch64 + arm64Bit: + arch: armv71 + plat: musllinux_1_2 + image: quay.io/pypa/musllinux_1_2_armv7l + python.architecture: armv71 64Bit: arch: x86_64 - plat: manylinux2014_x86_64 - image: quay.io/pypa/manylinux2014_x86_64 + plat: musllinux_1_2 + image: quay.io/pypa/musllinux_1_2_x86_64 python.architecture: x64 32Bit: arch: i686 - plat: manylinux2014_i686 - image: quay.io/pypa/manylinux2014_i686 + plat: musllinux_1_2 + image: quay.io/pypa/musllinux_1_2_i686 python.architecture: x86 pool: vmImage: "ubuntu-latest" @@ -71,8 +76,11 @@ stages: Python312: python.version: '3.12' python.architecture: 'x64' + Python313: + python.version: '3.13' + python.architecture: 'x64' pool: - vmImage: "windows-2019" + vmImage: "windows-2022" steps: - template: scripts/deps.yml - task: UsePythonVersion@0 @@ -101,8 +109,10 @@ stages: python.version: '3.11' Python312: python.version: '3.12' + Python313: + python.version: '3.13' pool: - vmImage: "macos-11" + vmImage: "macos-13" steps: - template: scripts/deps.yml - script: .azure/scripts/osx-python.sh '$(python.version)' From 0f58ace3bc54e4e3b029eca722f823e4115862d9 Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sat, 9 Nov 2024 17:22:00 -0800 Subject: [PATCH 02/43] Work on bumpversion --- .bumpversion.cfg | 6 +++--- doc/CHANGELOG.rst | 2 +- jpype/__init__.py | 2 +- native/java/org/jpype/JPypeContext.java | 2 +- native/python/pyjp_module.cpp | 2 +- pyproject.toml | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 456d45728..31e8ff4cf 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,10 +1,10 @@ [bumpversion] -current_version = 1.5.1_dev0 +current_version = 1.5.1.dev0 commit = True tag = False parse = (?P\d+)\.(?P\d+)\.(?P\d+)(\_(?P[a-z]+)(?P\d+))? serialize = - {major}.{minor}.{patch}_{release}{build} + {major}.{minor}.{patch}.{release}{build} {major}.{minor}.{patch} [bumpversion:part:release] @@ -16,7 +16,7 @@ values = [bumpversion:part:build] -[bumpversion:file:setup.py] +[bumpversion:file:pyproject.toml] [bumpversion:file:native/python/pyjp_module.cpp] diff --git a/doc/CHANGELOG.rst b/doc/CHANGELOG.rst index dd61866c7..f63cad3b9 100644 --- a/doc/CHANGELOG.rst +++ b/doc/CHANGELOG.rst @@ -5,7 +5,7 @@ This changelog *only* contains changes from the *first* pypi release (0.5.4.3) o Latest Changes: -- **1.5.1_dev0 - 2023-12-15** +- **1.5.1.dev0 - 2023-12-15** - Allow access to default methods implemented in interfaces when using ``@JImplements``. diff --git a/jpype/__init__.py b/jpype/__init__.py index c17f43065..c3d369e82 100644 --- a/jpype/__init__.py +++ b/jpype/__init__.py @@ -52,7 +52,7 @@ __all__.extend(_jcustomizer.__all__) # type: ignore[name-defined] __all__.extend(_gui.__all__) # type: ignore[name-defined] -__version__ = "1.5.1_dev0" +__version__ = "1.5.1.dev0" __version_info__ = __version__.split('.') diff --git a/native/java/org/jpype/JPypeContext.java b/native/java/org/jpype/JPypeContext.java index 708e81b62..2b3afcc0f 100644 --- a/native/java/org/jpype/JPypeContext.java +++ b/native/java/org/jpype/JPypeContext.java @@ -73,7 +73,7 @@ public class JPypeContext { - public final String VERSION = "1.5.1_dev0"; + public final String VERSION = "1.5.1.dev0"; private static JPypeContext INSTANCE = new JPypeContext(); // This is the C++ portion of the context. diff --git a/native/python/pyjp_module.cpp b/native/python/pyjp_module.cpp index 0b04e33e1..28cf60d3c 100644 --- a/native/python/pyjp_module.cpp +++ b/native/python/pyjp_module.cpp @@ -733,7 +733,7 @@ PyMODINIT_FUNC PyInit__jpype() #ifdef Py_GIL_DISABLED PyUnstable_Module_SetGIL(module, Py_MOD_GIL_NOT_USED); #endif - PyModule_AddStringConstant(module, "__version__", "1.5.1_dev0"); + PyModule_AddStringConstant(module, "__version__", "1.5.1.dev0"); // Our module will be used for PyFrame object and it is a requirement that // we have a builtins in our dictionary. diff --git a/pyproject.toml b/pyproject.toml index f35392751..0b380fca3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta" [project] name = "JPype1" -version = '1.5.0.dev0' +version = '1.5.1.dev0' authors = [ {name = "Steve Menard", email = "devilwolf@users.sourceforge.net"}, ] From 0693b9be497155307f8a7bc9c402d7ce0647c2ca Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sat, 9 Nov 2024 17:22:46 -0800 Subject: [PATCH 03/43] Another bumpversion change --- .bumpversion.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 31e8ff4cf..fa3bb515b 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -2,7 +2,7 @@ current_version = 1.5.1.dev0 commit = True tag = False -parse = (?P\d+)\.(?P\d+)\.(?P\d+)(\_(?P[a-z]+)(?P\d+))? +parse = (?P\d+)\.(?P\d+)\.(?P\d+)(\.(?P[a-z]+)(?P\d+))? serialize = {major}.{minor}.{patch}.{release}{build} {major}.{minor}.{patch} From 2f485278b1bb00ab8ddb61de2c6b5a1b6521f98f Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sat, 9 Nov 2024 17:22:58 -0800 Subject: [PATCH 04/43] =?UTF-8?q?Bump=20version:=201.5.1.dev0=20=E2=86=92?= =?UTF-8?q?=201.5.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- doc/CHANGELOG.rst | 1 + jpype/__init__.py | 2 +- native/java/org/jpype/JPypeContext.java | 2 +- native/python/pyjp_module.cpp | 2 +- pyproject.toml | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index fa3bb515b..8f0d430da 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.5.1.dev0 +current_version = 1.5.1 commit = True tag = False parse = (?P\d+)\.(?P\d+)\.(?P\d+)(\.(?P[a-z]+)(?P\d+))? diff --git a/doc/CHANGELOG.rst b/doc/CHANGELOG.rst index f63cad3b9..9711249ca 100644 --- a/doc/CHANGELOG.rst +++ b/doc/CHANGELOG.rst @@ -4,6 +4,7 @@ Changelog This changelog *only* contains changes from the *first* pypi release (0.5.4.3) onwards. Latest Changes: +- **1.5.1 - 2024-11-09** - **1.5.1.dev0 - 2023-12-15** diff --git a/jpype/__init__.py b/jpype/__init__.py index c3d369e82..1daaa6ca3 100644 --- a/jpype/__init__.py +++ b/jpype/__init__.py @@ -52,7 +52,7 @@ __all__.extend(_jcustomizer.__all__) # type: ignore[name-defined] __all__.extend(_gui.__all__) # type: ignore[name-defined] -__version__ = "1.5.1.dev0" +__version__ = "1.5.1" __version_info__ = __version__.split('.') diff --git a/native/java/org/jpype/JPypeContext.java b/native/java/org/jpype/JPypeContext.java index 2b3afcc0f..a2b039c75 100644 --- a/native/java/org/jpype/JPypeContext.java +++ b/native/java/org/jpype/JPypeContext.java @@ -73,7 +73,7 @@ public class JPypeContext { - public final String VERSION = "1.5.1.dev0"; + public final String VERSION = "1.5.1"; private static JPypeContext INSTANCE = new JPypeContext(); // This is the C++ portion of the context. diff --git a/native/python/pyjp_module.cpp b/native/python/pyjp_module.cpp index 28cf60d3c..64f252fd2 100644 --- a/native/python/pyjp_module.cpp +++ b/native/python/pyjp_module.cpp @@ -733,7 +733,7 @@ PyMODINIT_FUNC PyInit__jpype() #ifdef Py_GIL_DISABLED PyUnstable_Module_SetGIL(module, Py_MOD_GIL_NOT_USED); #endif - PyModule_AddStringConstant(module, "__version__", "1.5.1.dev0"); + PyModule_AddStringConstant(module, "__version__", "1.5.1"); // Our module will be used for PyFrame object and it is a requirement that // we have a builtins in our dictionary. diff --git a/pyproject.toml b/pyproject.toml index 0b380fca3..7a49f218d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta" [project] name = "JPype1" -version = '1.5.1.dev0' +version = '1.5.1' authors = [ {name = "Steve Menard", email = "devilwolf@users.sourceforge.net"}, ] From 528863e5d328baebf4f0578b2e784750a52b7b46 Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sat, 9 Nov 2024 17:24:07 -0800 Subject: [PATCH 05/43] Proposed changelog --- doc/CHANGELOG.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/CHANGELOG.rst b/doc/CHANGELOG.rst index 9711249ca..990befdd3 100644 --- a/doc/CHANGELOG.rst +++ b/doc/CHANGELOG.rst @@ -6,7 +6,9 @@ This changelog *only* contains changes from the *first* pypi release (0.5.4.3) o Latest Changes: - **1.5.1 - 2024-11-09** -- **1.5.1.dev0 - 2023-12-15** + - Future proofing for Python 3.14 + + - Support for Python 3.13 - Allow access to default methods implemented in interfaces when using ``@JImplements``. From 634bb64e8a854c6652df4889619fa4e4e77ab15b Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sat, 16 Nov 2024 13:32:57 -0800 Subject: [PATCH 06/43] Roll back some of the options --- .azure/release.yml | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/.azure/release.yml b/.azure/release.yml index 4cf2280a6..7784ff05b 100644 --- a/.azure/release.yml +++ b/.azure/release.yml @@ -35,20 +35,24 @@ stages: # plat: manylinux2014_aarch64 # image: quay.io/pypa/manylinux2014_aarch64 # python.architecture: aarch64 - arm64Bit: - arch: armv71 - plat: musllinux_1_2 - image: quay.io/pypa/musllinux_1_2_armv7l - python.architecture: armv71 + #arm64Bit: + # arch: armv71 + # plat: musllinux_1_2 + # image: quay.io/pypa/musllinux_1_2_armv7l + # python.architecture: armv71 64Bit: arch: x86_64 - plat: musllinux_1_2 - image: quay.io/pypa/musllinux_1_2_x86_64 + plat: manylinux2010_x86_64 + image: quay.io/pypa/manylinux2010_x86_64 +# plat: musllinux_1_2 +# image: quay.io/pypa/musllinux_1_2_x86_64 python.architecture: x64 32Bit: arch: i686 - plat: musllinux_1_2 - image: quay.io/pypa/musllinux_1_2_i686 + plat: manylinux2010_i686 + image: quay.io/pypa/manylinux2010_i686 +# plat: musllinux_1_2 +# image: quay.io/pypa/musllinux_1_2_i686 python.architecture: x86 pool: vmImage: "ubuntu-latest" @@ -76,11 +80,12 @@ stages: Python312: python.version: '3.12' python.architecture: 'x64' - Python313: - python.version: '3.13' - python.architecture: 'x64' +# Python313: +# python.version: '3.13' +# python.architecture: 'x64' pool: - vmImage: "windows-2022" +# vmImage: "windows-2022" + vmImage: "windows-2019" steps: - template: scripts/deps.yml - task: UsePythonVersion@0 @@ -109,10 +114,11 @@ stages: python.version: '3.11' Python312: python.version: '3.12' - Python313: - python.version: '3.13' +# Python313: +# python.version: '3.13' pool: - vmImage: "macos-13" + vmImage: "macos-11" +# vmImage: "macos-13" steps: - template: scripts/deps.yml - script: .azure/scripts/osx-python.sh '$(python.version)' From 6040496b2877c6d2ac3c94d0cd44b0d196e6e6c1 Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sat, 16 Nov 2024 13:34:28 -0800 Subject: [PATCH 07/43] Reduce size of matrix --- .azure/release.yml | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/.azure/release.yml b/.azure/release.yml index 7784ff05b..a2ca281f0 100644 --- a/.azure/release.yml +++ b/.azure/release.yml @@ -68,18 +68,18 @@ stages: Python38: python.version: '3.8' python.architecture: 'x64' - Python39: - python.version: '3.9' - python.architecture: 'x64' - Python310: - python.version: '3.10' - python.architecture: 'x64' - Python311: - python.version: '3.11' - python.architecture: 'x64' - Python312: - python.version: '3.12' - python.architecture: 'x64' +# Python39: +# python.version: '3.9' +# python.architecture: 'x64' +# Python310: +# python.version: '3.10' +# python.architecture: 'x64' +# Python311: +# python.version: '3.11' +# python.architecture: 'x64' +# Python312: +# python.version: '3.12' +# python.architecture: 'x64' # Python313: # python.version: '3.13' # python.architecture: 'x64' @@ -106,14 +106,14 @@ stages: matrix: Python38: python.version: '3.8' - Python39: - python.version: '3.9' - Python310: - python.version: '3.10' - Python311: - python.version: '3.11' - Python312: - python.version: '3.12' +# Python39: +# python.version: '3.9' +# Python310: +# python.version: '3.10' +# Python311: +# python.version: '3.11' +# Python312: +# python.version: '3.12' # Python313: # python.version: '3.13' pool: From 7859017b7926303ba5b6d9c947990a0e73cfd1cd Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sat, 16 Nov 2024 14:43:27 -0800 Subject: [PATCH 08/43] Working around case issue --- .azure/release.yml | 2 +- .azure/scripts/sdist.yml | 2 +- .azure/scripts/wheels-linux.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.azure/release.yml b/.azure/release.yml index a2ca281f0..5812eb4cb 100644 --- a/.azure/release.yml +++ b/.azure/release.yml @@ -10,7 +10,7 @@ pr: - .azure/release.yml variables: - package_name: JPype1 + package_name: jpype1 stages: - stage: Initial diff --git a/.azure/scripts/sdist.yml b/.azure/scripts/sdist.yml index ecf1fbe37..2dda93e93 100644 --- a/.azure/scripts/sdist.yml +++ b/.azure/scripts/sdist.yml @@ -1,7 +1,7 @@ steps: - task: UsePythonVersion@0 inputs: - versionSpec: '3.8' + versionSpec: '3.10' - script: | python -m pip install build python -m build ./ --sdist diff --git a/.azure/scripts/wheels-linux.yml b/.azure/scripts/wheels-linux.yml index b88b3948f..92c98b11e 100644 --- a/.azure/scripts/wheels-linux.yml +++ b/.azure/scripts/wheels-linux.yml @@ -1,7 +1,7 @@ steps: - task: UsePythonVersion@0 inputs: - versionSpec: '3.8' + versionSpec: '3.10' - task: DownloadPipelineArtifact@2 inputs: From d07579dea9aab7a7cdb7761c63821c7546e9008b Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sat, 16 Nov 2024 17:05:02 -0800 Subject: [PATCH 09/43] Still dealing with lowercase --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7a49f218d..48d1bab30 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta" [project] -name = "JPype1" +name = "jpype1" version = '1.5.1' authors = [ {name = "Steve Menard", email = "devilwolf@users.sourceforge.net"}, From ece255d1d8d03bfc2bbf34746a9d4978b892e525 Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sat, 16 Nov 2024 17:11:05 -0800 Subject: [PATCH 10/43] Try yet again --- .azure/scripts/wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/scripts/wheels.yml b/.azure/scripts/wheels.yml index c2c1b42e2..8799fd359 100644 --- a/.azure/scripts/wheels.yml +++ b/.azure/scripts/wheels.yml @@ -16,7 +16,7 @@ steps: displayName: 'Show wheelhouse' - script: | - python -m pip install JPype1 --no-index -f wheelhouse + python -m pip install jpype1 --no-index -f wheelhouse displayName: 'Install module' - script: | From 8e0abe3db1f823e81c9d95b6523be9438b0c9a52 Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sat, 16 Nov 2024 18:28:19 -0800 Subject: [PATCH 11/43] Still not working --- .azure/release.yml | 4 ++-- .azure/scripts/wheels.yml | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.azure/release.yml b/.azure/release.yml index 5812eb4cb..b87b55571 100644 --- a/.azure/release.yml +++ b/.azure/release.yml @@ -96,7 +96,7 @@ stages: parameters: version: '8' - template: scripts/wheels.yml - - template: scripts/publish-dist.yml + #- template: scripts/publish-dist.yml - job: OSX condition: eq(1,1) @@ -127,4 +127,4 @@ stages: parameters: version: '8' - template: scripts/wheels.yml - - template: scripts/publish-dist.yml + #- template: scripts/publish-dist.yml diff --git a/.azure/scripts/wheels.yml b/.azure/scripts/wheels.yml index 8799fd359..70c0f0032 100644 --- a/.azure/scripts/wheels.yml +++ b/.azure/scripts/wheels.yml @@ -29,6 +29,11 @@ steps: ls lib/ displayName: 'Check deps' +- task: PublishPipelineArtifact@0 + inputs: + artifactName: 'artifact_$(Agent.JobName)_$(Agent.OS)_$(python.architecture)' + targetPath: 'dist' + - script: | python -m pytest -v --junit-xml=build/test/test.xml test/jpypetest --checkjni --fast displayName: 'Test module' From 89de4342f3b935308438b3b23327e6aed141f31f Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sat, 16 Nov 2024 18:48:06 -0800 Subject: [PATCH 12/43] Merge conflict --- .azure/scripts/wheels.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.azure/scripts/wheels.yml b/.azure/scripts/wheels.yml index ae9c15cbb..a10c8d627 100644 --- a/.azure/scripts/wheels.yml +++ b/.azure/scripts/wheels.yml @@ -8,10 +8,6 @@ steps: - script: | python -m pip wheel . -w wheelhouse/ displayName: 'Build wheel' - inputs: - PathtoPublish: 'wheelhouse' - ArtifactName: 'python-wheels' - publishLocation: 'Container' - script: | ls -lh wheelhouse From 793dede87967c4e56d6c5520621d0d469e22ad8a Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sat, 16 Nov 2024 18:50:22 -0800 Subject: [PATCH 13/43] OSX change --- .azure/release.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.azure/release.yml b/.azure/release.yml index b87b55571..45130e72b 100644 --- a/.azure/release.yml +++ b/.azure/release.yml @@ -117,8 +117,7 @@ stages: # Python313: # python.version: '3.13' pool: - vmImage: "macos-11" -# vmImage: "macos-13" + vmImage: "macos-13" steps: - template: scripts/deps.yml - script: .azure/scripts/osx-python.sh '$(python.version)' From 5b63912d4650a5c05dc14fd56c12bcbdcbc0e41a Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sun, 17 Nov 2024 08:42:51 -0800 Subject: [PATCH 14/43] Testing release --- .azure/release.yml | 50 +++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/.azure/release.yml b/.azure/release.yml index 45130e72b..77636a645 100644 --- a/.azure/release.yml +++ b/.azure/release.yml @@ -42,17 +42,17 @@ stages: # python.architecture: armv71 64Bit: arch: x86_64 - plat: manylinux2010_x86_64 - image: quay.io/pypa/manylinux2010_x86_64 -# plat: musllinux_1_2 -# image: quay.io/pypa/musllinux_1_2_x86_64 +# plat: manylinux2010_x86_64 +# image: quay.io/pypa/manylinux2010_x86_64 + plat: musllinux_1_2 + image: quay.io/pypa/musllinux_1_2_x86_64 python.architecture: x64 32Bit: arch: i686 - plat: manylinux2010_i686 - image: quay.io/pypa/manylinux2010_i686 -# plat: musllinux_1_2 -# image: quay.io/pypa/musllinux_1_2_i686 +# plat: manylinux2010_i686 +# image: quay.io/pypa/manylinux2010_i686 + plat: musllinux_1_2 + image: quay.io/pypa/musllinux_1_2_i686 python.architecture: x86 pool: vmImage: "ubuntu-latest" @@ -65,9 +65,9 @@ stages: condition: eq(1,1) strategy: matrix: - Python38: - python.version: '3.8' - python.architecture: 'x64' +# Python38: +# python.version: '3.8' +# python.architecture: 'x64' # Python39: # python.version: '3.9' # python.architecture: 'x64' @@ -77,9 +77,9 @@ stages: # Python311: # python.version: '3.11' # python.architecture: 'x64' -# Python312: -# python.version: '3.12' -# python.architecture: 'x64' + Python312: + python.version: '3.12' + python.architecture: 'x64' # Python313: # python.version: '3.13' # python.architecture: 'x64' @@ -99,23 +99,23 @@ stages: #- template: scripts/publish-dist.yml - job: OSX - condition: eq(1,1) + condition: eq(0,1) variables: python.architecture: 'x64' strategy: matrix: Python38: python.version: '3.8' -# Python39: -# python.version: '3.9' -# Python310: -# python.version: '3.10' -# Python311: -# python.version: '3.11' -# Python312: -# python.version: '3.12' -# Python313: -# python.version: '3.13' + Python39: + python.version: '3.9' + Python310: + python.version: '3.10' + Python311: + python.version: '3.11' + Python312: + python.version: '3.12' + Python313: + python.version: '3.13' pool: vmImage: "macos-13" steps: From 52e2c077e3474ccc4682ff64a0e7999bbdee00d5 Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sun, 17 Nov 2024 09:06:57 -0800 Subject: [PATCH 15/43] Try manylinux2014 --- .azure/release.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.azure/release.yml b/.azure/release.yml index 77636a645..516a1f03f 100644 --- a/.azure/release.yml +++ b/.azure/release.yml @@ -42,17 +42,17 @@ stages: # python.architecture: armv71 64Bit: arch: x86_64 -# plat: manylinux2010_x86_64 -# image: quay.io/pypa/manylinux2010_x86_64 - plat: musllinux_1_2 - image: quay.io/pypa/musllinux_1_2_x86_64 + plat: manylinux2014_x86_64 + image: quay.io/pypa/manylinux2014_x86_64 +# plat: musllinux_1_2 +# image: quay.io/pypa/musllinux_1_2_x86_64 python.architecture: x64 32Bit: arch: i686 -# plat: manylinux2010_i686 -# image: quay.io/pypa/manylinux2010_i686 - plat: musllinux_1_2 - image: quay.io/pypa/musllinux_1_2_i686 + plat: manylinux2014_i686 + image: quay.io/pypa/manylinux2014_i686 +# plat: musllinux_1_2 +# image: quay.io/pypa/musllinux_1_2_i686 python.architecture: x86 pool: vmImage: "ubuntu-latest" From 0905eb0ee29db2c9b6b363a6ec8387e730fa242d Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sun, 17 Nov 2024 09:28:35 -0800 Subject: [PATCH 16/43] Run the site installed package not the local one --- .azure/scripts/wheels.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.azure/scripts/wheels.yml b/.azure/scripts/wheels.yml index a10c8d627..29a2eaf3c 100644 --- a/.azure/scripts/wheels.yml +++ b/.azure/scripts/wheels.yml @@ -34,6 +34,7 @@ steps: targetPath: 'dist' - script: | + rm -Rf jpype python -m pytest -v --junit-xml=build/test/test.xml test/jpypetest --checkjni --fast displayName: 'Test module' From 5d0c0ecbfdd81a80954252138fb7fb1abb0ea12e Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sun, 17 Nov 2024 11:33:06 -0800 Subject: [PATCH 17/43] Fix for lineno --- native/common/jp_exception.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/native/common/jp_exception.cpp b/native/common/jp_exception.cpp index a3e3ef902..f56342648 100644 --- a/native/common/jp_exception.cpp +++ b/native/common/jp_exception.cpp @@ -563,6 +563,10 @@ JPPyObject PyTrace_FromJavaException(JPJavaFrame& frame, jthrowable th, jthrowab jint lineNum = frame.CallIntMethodA(frame.GetObjectArrayElement(obj, i + 3), context->_java_lang_Integer->m_IntValueID, nullptr); + // sending -1 will cause issues on Windows + if (lineNum<0) + lineNum = 0; + last_traceback = tb_create(last_traceback, dict, filename.c_str(), method.c_str(), lineNum); frame.DeleteLocalRef(jclassname); From c07b2255dcf2dec8a045dc76f7a6ae318d38d90c Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Sun, 17 Nov 2024 22:50:22 +0100 Subject: [PATCH 18/43] [ci/test] use pip to produce a development install --- .azure/scripts/test.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.azure/scripts/test.yml b/.azure/scripts/test.yml index 660b9ae25..6ecae2bc2 100644 --- a/.azure/scripts/test.yml +++ b/.azure/scripts/test.yml @@ -12,8 +12,7 @@ steps: version: '$(jdk.version)' - script: | - python -m pip install setuptools - python setup.py develop + python -m pip install -e[test] displayName: 'Build module' - script: | From 85edcffdbb64670d2afc3c4b85e4e10275614fa2 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Sun, 17 Nov 2024 22:54:25 +0100 Subject: [PATCH 19/43] fix --- .azure/scripts/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/scripts/test.yml b/.azure/scripts/test.yml index 6ecae2bc2..8acefaac9 100644 --- a/.azure/scripts/test.yml +++ b/.azure/scripts/test.yml @@ -12,7 +12,7 @@ steps: version: '$(jdk.version)' - script: | - python -m pip install -e[test] + python -m pip install -e .[test] displayName: 'Build module' - script: | From af12a143b6babf4c0454a6a2075824604004d62b Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Sun, 17 Nov 2024 23:07:44 +0100 Subject: [PATCH 20/43] [ci/test] install setuptools in stage "install test" --- .azure/scripts/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.azure/scripts/test.yml b/.azure/scripts/test.yml index 8acefaac9..b391edc63 100644 --- a/.azure/scripts/test.yml +++ b/.azure/scripts/test.yml @@ -21,6 +21,7 @@ steps: displayName: 'Check module' - script: | + pip install setuptools python setup.py test_java pip install -r test-requirements.txt displayName: 'Install test' From 35a1342b3459e3ed0ad8e89e54a05d3cbe664270 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Sun, 17 Nov 2024 23:21:48 +0100 Subject: [PATCH 21/43] [ci/test] install setuptools in stage "install test" (the right file...) also disable manylinux stages for testing --- .azure/release.yml | 4 ++-- .azure/scripts/wheels.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.azure/release.yml b/.azure/release.yml index 516a1f03f..4556a3eb7 100644 --- a/.azure/release.yml +++ b/.azure/release.yml @@ -26,7 +26,7 @@ stages: jobs: # From https://iscinumpy.gitlab.io/post/azure-devops-python-wheels/ - job: ManyLinux - condition: eq(1,1) + condition: eq(0,1) # todo: renable after testing windoze strategy: matrix: # Disabled because it is fetching beta images @@ -43,7 +43,7 @@ stages: 64Bit: arch: x86_64 plat: manylinux2014_x86_64 - image: quay.io/pypa/manylinux2014_x86_64 + image: quay.io/pypa/manylinux2014w_x86_64 # plat: musllinux_1_2 # image: quay.io/pypa/musllinux_1_2_x86_64 python.architecture: x64 diff --git a/.azure/scripts/wheels.yml b/.azure/scripts/wheels.yml index 29a2eaf3c..835a88459 100644 --- a/.azure/scripts/wheels.yml +++ b/.azure/scripts/wheels.yml @@ -2,7 +2,7 @@ steps: - script: | mkdir -p dist - python -m pip install --upgrade pip + python -m pip install --upgrade pip setuptools displayName: 'Install dependencies' - script: | From 34a0c6d54ea0501a6bd5c05048412b92d2ef9e36 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Sun, 17 Nov 2024 23:32:11 +0100 Subject: [PATCH 22/43] split stages test_java and requirements installation --- .azure/scripts/wheels.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.azure/scripts/wheels.yml b/.azure/scripts/wheels.yml index 835a88459..8913f3fad 100644 --- a/.azure/scripts/wheels.yml +++ b/.azure/scripts/wheels.yml @@ -2,7 +2,7 @@ steps: - script: | mkdir -p dist - python -m pip install --upgrade pip setuptools + python -m pip install --upgrade pip setuptools -r test-requirements.txt displayName: 'Install dependencies' - script: | @@ -20,8 +20,7 @@ steps: - script: | python setup.py test_java - python -m pip install -r test-requirements.txt - displayName: 'Install test' + displayName: 'Build java tests' - script: | ls -l From b1c5f7306a66d9f222ec1bc171bf8de5d109ffdb Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Sun, 17 Nov 2024 23:36:43 +0100 Subject: [PATCH 23/43] [ci/releases] add aarch64 to matrix (manylinux) --- .azure/release.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.azure/release.yml b/.azure/release.yml index 4556a3eb7..2b3c8c142 100644 --- a/.azure/release.yml +++ b/.azure/release.yml @@ -26,15 +26,14 @@ stages: jobs: # From https://iscinumpy.gitlab.io/post/azure-devops-python-wheels/ - job: ManyLinux - condition: eq(0,1) # todo: renable after testing windoze + condition: eq(1,1) strategy: matrix: - # Disabled because it is fetching beta images - # 64Bit2014: - # arch: aarch64 - # plat: manylinux2014_aarch64 - # image: quay.io/pypa/manylinux2014_aarch64 - # python.architecture: aarch64 + aarch64: + arch: aarch64 + plat: manylinux2014_aarch64 + image: quay.io/pypa/manylinux2014_aarch64 + python.architecture: aarch64 #arm64Bit: # arch: armv71 # plat: musllinux_1_2 From 28e9ccdd532fb985f39fe136999fb30fe712bc7f Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Sun, 17 Nov 2024 23:46:28 +0100 Subject: [PATCH 24/43] fix typo --- .azure/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/release.yml b/.azure/release.yml index 2b3c8c142..d20159a93 100644 --- a/.azure/release.yml +++ b/.azure/release.yml @@ -42,7 +42,7 @@ stages: 64Bit: arch: x86_64 plat: manylinux2014_x86_64 - image: quay.io/pypa/manylinux2014w_x86_64 + image: quay.io/pypa/manylinux2014_x86_64 # plat: musllinux_1_2 # image: quay.io/pypa/musllinux_1_2_x86_64 python.architecture: x64 From 5c1de82e93fe127a5064682064832a31320641d6 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 00:23:37 +0100 Subject: [PATCH 25/43] update python version in pyproject.toml --- pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 48d1bab30..72f10b945 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,21 +16,21 @@ maintainers = [ ] description = "A Python to Java bridge" readme = "README.rst" -requires-python = ">=3.7" +requires-python = ">=3.8" license = {text = "License :: OSI Approved :: Apache Software License"} classifiers = [ 'Programming Language :: Python :: 3', - '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 :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', 'Topic :: Software Development', 'Topic :: Scientific/Engineering', ] dependencies = [ 'packaging', - 'typing_extensions ; python_version< "3.8"', ] From fbe74cde4751023c6a67db306636e972b443dc13 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 00:30:21 +0100 Subject: [PATCH 26/43] [ci] wrap UsePythonVersion as template check if Python-3.13 gets downloaded --- .azure/release.yml | 26 +++++++++++++------------- .azure/scripts/python.yml | 20 ++++++++++++++++++++ .azure/scripts/test.yml | 10 ++++------ .azure/scripts/wheels-linux.yml | 3 --- 4 files changed, 37 insertions(+), 22 deletions(-) create mode 100644 .azure/scripts/python.yml diff --git a/.azure/release.yml b/.azure/release.yml index d20159a93..1b96f545b 100644 --- a/.azure/release.yml +++ b/.azure/release.yml @@ -1,6 +1,6 @@ # JPype Release pipeline trigger: none -pr: +pr: branches: include: - releases/* @@ -16,7 +16,7 @@ stages: - stage: Initial jobs: - job: SourceDistribution - pool: + pool: vmImage: "ubuntu-latest" steps: - template: scripts/sdist.yml @@ -39,14 +39,14 @@ stages: # plat: musllinux_1_2 # image: quay.io/pypa/musllinux_1_2_armv7l # python.architecture: armv71 - 64Bit: + x86_64: arch: x86_64 plat: manylinux2014_x86_64 image: quay.io/pypa/manylinux2014_x86_64 # plat: musllinux_1_2 # image: quay.io/pypa/musllinux_1_2_x86_64 python.architecture: x64 - 32Bit: + i686: arch: i686 plat: manylinux2014_i686 image: quay.io/pypa/manylinux2014_i686 @@ -79,26 +79,26 @@ stages: Python312: python.version: '3.12' python.architecture: 'x64' -# Python313: -# python.version: '3.13' -# python.architecture: 'x64' + Python313: + python.version: '3.13' + python.architecture: 'x64' pool: # vmImage: "windows-2022" vmImage: "windows-2019" steps: - template: scripts/deps.yml - - task: UsePythonVersion@0 - inputs: - versionSpec: '$(python.version)' + - template: scripts/python.yml + parameters: + version: '$(python.version)' architecture: '$(python.architecture)' - template: scripts/jdk.yml parameters: version: '8' - template: scripts/wheels.yml - #- template: scripts/publish-dist.yml + - template: scripts/publish-dist.yml - job: OSX - condition: eq(0,1) + condition: eq(1,1) variables: python.architecture: 'x64' strategy: @@ -125,4 +125,4 @@ stages: parameters: version: '8' - template: scripts/wheels.yml - #- template: scripts/publish-dist.yml + - template: scripts/publish-dist.yml diff --git a/.azure/scripts/python.yml b/.azure/scripts/python.yml new file mode 100644 index 000000000..a75e00f52 --- /dev/null +++ b/.azure/scripts/python.yml @@ -0,0 +1,20 @@ +parameters: +- name: version + type: string + default: '3.12' + +- name: architecture + type: string + default: 'x86_64' + +steps: + - task: UsePythonVersion@0 + inputs: + architecture: '$(architecture)' + versionSpec: '$(version)' + disableDownloadFromRegistry: false # boolean. Disable downloading releases from the GitHub registry. Default: false. + allowUnstable: true # boolean. Optional. Use when disableDownloadFromRegistry = false. Allow downloading unstable releases. Default: false. + githubToken: '$(githubToken)' # global (secret) variable to allow API access to Github (for not hitting a rate limit while downloading). + - bash: | + [[ $(python --version) -eq '$version' ]] + displayName: check version \ No newline at end of file diff --git a/.azure/scripts/test.yml b/.azure/scripts/test.yml index b391edc63..a4e9bca41 100644 --- a/.azure/scripts/test.yml +++ b/.azure/scripts/test.yml @@ -1,11 +1,9 @@ # This task tests individual platforms and versions steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(python.version)' - disableDownloadFromRegistry: false # boolean. Disable downloading releases from the GitHub registry. Default: false. - allowUnstable: true # boolean. Optional. Use when disableDownloadFromRegistry = false. Allow downloading unstable releases. Default: false. - githubToken: '$(githubToken)' + +- template: python.yml + parameters: + version: '$(python.version)' - template: jdk.yml parameters: diff --git a/.azure/scripts/wheels-linux.yml b/.azure/scripts/wheels-linux.yml index 92c98b11e..b0b502a5d 100644 --- a/.azure/scripts/wheels-linux.yml +++ b/.azure/scripts/wheels-linux.yml @@ -1,7 +1,4 @@ steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '3.10' - task: DownloadPipelineArtifact@2 inputs: From 7334fef9189813768ec8848986808c992dcdbbce Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 00:44:50 +0100 Subject: [PATCH 27/43] pass vars not as strings --- .azure/scripts/python.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.azure/scripts/python.yml b/.azure/scripts/python.yml index a75e00f52..14685a490 100644 --- a/.azure/scripts/python.yml +++ b/.azure/scripts/python.yml @@ -10,11 +10,11 @@ parameters: steps: - task: UsePythonVersion@0 inputs: - architecture: '$(architecture)' - versionSpec: '$(version)' + architecture: $(architecture) + versionSpec: $(version) disableDownloadFromRegistry: false # boolean. Disable downloading releases from the GitHub registry. Default: false. allowUnstable: true # boolean. Optional. Use when disableDownloadFromRegistry = false. Allow downloading unstable releases. Default: false. - githubToken: '$(githubToken)' # global (secret) variable to allow API access to Github (for not hitting a rate limit while downloading). + githubToken: $(githubToken) # global (secret) variable to allow API access to Github (for not hitting a rate limit while downloading). - bash: | [[ $(python --version) -eq '$version' ]] displayName: check version \ No newline at end of file From 8da632eaa53f3dd97b6a1376973948d1ade967a9 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 00:58:06 +0100 Subject: [PATCH 28/43] variable access pattern --- .azure/scripts/python.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.azure/scripts/python.yml b/.azure/scripts/python.yml index 14685a490..4f939bad1 100644 --- a/.azure/scripts/python.yml +++ b/.azure/scripts/python.yml @@ -10,11 +10,12 @@ parameters: steps: - task: UsePythonVersion@0 inputs: - architecture: $(architecture) - versionSpec: $(version) + architecture: ${{ parameters.architecture }} + versionSpec: ${{ parameters.version }} disableDownloadFromRegistry: false # boolean. Disable downloading releases from the GitHub registry. Default: false. allowUnstable: true # boolean. Optional. Use when disableDownloadFromRegistry = false. Allow downloading unstable releases. Default: false. - githubToken: $(githubToken) # global (secret) variable to allow API access to Github (for not hitting a rate limit while downloading). + # todo: do we need this kind of variable access pattern? + githubToken: ${{ githubToken }} # global (secret) variable to allow API access to Github (for not hitting a rate limit while downloading). - bash: | [[ $(python --version) -eq '$version' ]] displayName: check version \ No newline at end of file From 550e2073880210c6018df61ab902714175de8ea4 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 01:04:02 +0100 Subject: [PATCH 29/43] fix gh token var --- .azure/scripts/python.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.azure/scripts/python.yml b/.azure/scripts/python.yml index 4f939bad1..0548613f5 100644 --- a/.azure/scripts/python.yml +++ b/.azure/scripts/python.yml @@ -14,8 +14,7 @@ steps: versionSpec: ${{ parameters.version }} disableDownloadFromRegistry: false # boolean. Disable downloading releases from the GitHub registry. Default: false. allowUnstable: true # boolean. Optional. Use when disableDownloadFromRegistry = false. Allow downloading unstable releases. Default: false. - # todo: do we need this kind of variable access pattern? - githubToken: ${{ githubToken }} # global (secret) variable to allow API access to Github (for not hitting a rate limit while downloading). + githubToken: $(githubToken) # global (secret) variable to allow API access to Github (for not hitting a rate limit while downloading). - bash: | [[ $(python --version) -eq '$version' ]] displayName: check version \ No newline at end of file From b255301dac7ea5fc0fd76cf57457dbaf5b75e212 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 01:12:29 +0100 Subject: [PATCH 30/43] fix default arch --- .azure/scripts/python.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/scripts/python.yml b/.azure/scripts/python.yml index 0548613f5..a5f8eb53b 100644 --- a/.azure/scripts/python.yml +++ b/.azure/scripts/python.yml @@ -5,7 +5,7 @@ parameters: - name: architecture type: string - default: 'x86_64' + default: 'x64' steps: - task: UsePythonVersion@0 From d6bca218c42105f4da55a75edd5acca4b9f5198b Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 01:17:57 +0100 Subject: [PATCH 31/43] fix check --- .azure/scripts/python.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.azure/scripts/python.yml b/.azure/scripts/python.yml index a5f8eb53b..d99f23127 100644 --- a/.azure/scripts/python.yml +++ b/.azure/scripts/python.yml @@ -16,5 +16,6 @@ steps: allowUnstable: true # boolean. Optional. Use when disableDownloadFromRegistry = false. Allow downloading unstable releases. Default: false. githubToken: $(githubToken) # global (secret) variable to allow API access to Github (for not hitting a rate limit while downloading). - bash: | - [[ $(python --version) -eq '$version' ]] - displayName: check version \ No newline at end of file + echo AGENT_JOBSTATUS = $AGENT_JOBSTATUS + if [[ "$AGENT_JOBSTATUS" == "SucceededWithIssues" ]]; then exit 1; fi + displayName: Python ${{ parameters.version }} set as interpreter. From ecc9062dc86cb302df223c66a5617f0e9609b537 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 01:58:19 +0100 Subject: [PATCH 32/43] exclude python 3.7 from wheel creation --- .azure/scripts/build-wheels.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.azure/scripts/build-wheels.sh b/.azure/scripts/build-wheels.sh index 5b536772a..34799ce44 100755 --- a/.azure/scripts/build-wheels.sh +++ b/.azure/scripts/build-wheels.sh @@ -4,8 +4,9 @@ set -e -x # Collect the pythons pys=(/opt/python/cp*/bin) -# Exclude specific Pythons (3.6) +# Exclude specific Pythons (3.6, 3.7) pys=(${pys[@]//*36*/}) +pys=(${pys[@]//*37*/}) # Compile wheels for PYBIN in "${pys[@]}"; do From 5676c22646f16ce198d32751713eb75b649cc7b9 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 08:06:55 +0100 Subject: [PATCH 33/43] add Python 3.13 to osx-python.sh --- .azure/scripts/osx-python.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.azure/scripts/osx-python.sh b/.azure/scripts/osx-python.sh index 37d66a44e..aae36d427 100755 --- a/.azure/scripts/osx-python.sh +++ b/.azure/scripts/osx-python.sh @@ -26,6 +26,10 @@ case $PYTHON_VERSION in 3.12) FULL_VERSION=3.12.0 INSTALLER_NAME=python-$FULL_VERSION-macos11.pkg + ;; +3.13) + FULL_VERSION=3.13.0 + INSTALLER_NAME=python-$FULL_VERSION-macos11.pkg esac URL=https://www.python.org/ftp/python/$FULL_VERSION/$INSTALLER_NAME From 90e2ff69461dd652250f9b116a6118538394af23 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 08:23:20 +0100 Subject: [PATCH 34/43] set timeout to 360 min for manylinux --- .azure/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.azure/release.yml b/.azure/release.yml index 1b96f545b..e0b92eb3c 100644 --- a/.azure/release.yml +++ b/.azure/release.yml @@ -27,6 +27,7 @@ stages: # From https://iscinumpy.gitlab.io/post/azure-devops-python-wheels/ - job: ManyLinux condition: eq(1,1) + timeoutInMinutes: 360 strategy: matrix: aarch64: From 81f5ee6a3017b2ced7488b8b806400d2af1b155b Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 08:29:18 +0100 Subject: [PATCH 35/43] re-enable win jobs --- .azure/release.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.azure/release.yml b/.azure/release.yml index e0b92eb3c..80d9a8e80 100644 --- a/.azure/release.yml +++ b/.azure/release.yml @@ -65,18 +65,18 @@ stages: condition: eq(1,1) strategy: matrix: -# Python38: -# python.version: '3.8' -# python.architecture: 'x64' -# Python39: -# python.version: '3.9' -# python.architecture: 'x64' -# Python310: -# python.version: '3.10' -# python.architecture: 'x64' -# Python311: -# python.version: '3.11' -# python.architecture: 'x64' + Python38: + python.version: '3.8' + python.architecture: 'x64' + Python39: + python.version: '3.9' + python.architecture: 'x64' + Python310: + python.version: '3.10' + python.architecture: 'x64' + Python311: + python.version: '3.11' + python.architecture: 'x64' Python312: python.version: '3.12' python.architecture: 'x64' From e8f6ed3c2c12956e12aef259fd99f95b3433ea42 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 16:08:16 +0100 Subject: [PATCH 36/43] Squashed commit of the following: commit d8373371d5a96fe949c879ea150da606fb84940c Merge: 1a56a3b3 c474ee87 Author: Martin K. Scherer Date: Mon Nov 18 08:34:35 2024 +0100 Merge pull request #1235 from Thrameos/win_gc Fix for GC on windows commit c474ee87ed59e054ad1dc189b27a76e061ef663d Author: Karl Nelson Date: Sun Nov 17 20:25:19 2024 -0800 Fix tab/spaces commit 3d2577ae91b229536dde4d6ba5df4d4a41ad54b1 Author: Karl Nelson Date: Sat Nov 16 18:15:44 2024 -0800 Fix for GC on windows --- native/common/include/jp_gc.h | 9 ++++++++- native/common/jp_gc.cpp | 26 +++++++++++++++++++++++-- native/java/org/jpype/JPypeContext.java | 25 ++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/native/common/include/jp_gc.h b/native/common/include/jp_gc.h index c20117c1c..cad182122 100644 --- a/native/common/include/jp_gc.h +++ b/native/common/include/jp_gc.h @@ -56,8 +56,15 @@ class JPGarbageCollection bool java_triggered; PyObject *python_gc; jclass _SystemClass; + jclass _ContextClass; jmethodID _gcMethodID; + jmethodID _totalMemoryID; + jmethodID _freeMemoryID; + jmethodID _maxMemoryID; + jmethodID _usedMemoryID; + jmethodID _heapMemoryID; + size_t last_python; size_t last_java; size_t low_water; @@ -69,4 +76,4 @@ class JPGarbageCollection int python_triggered; } ; -#endif /* JP_GC_H */ \ No newline at end of file +#endif /* JP_GC_H */ diff --git a/native/common/jp_gc.cpp b/native/common/jp_gc.cpp index 505373580..6d2a47ce0 100644 --- a/native/common/jp_gc.cpp +++ b/native/common/jp_gc.cpp @@ -154,6 +154,14 @@ void JPGarbageCollection::init(JPJavaFrame& frame) _SystemClass = (jclass) frame.NewGlobalRef(frame.FindClass("java/lang/System")); _gcMethodID = frame.GetStaticMethodID(_SystemClass, "gc", "()V"); + jclass ctxt = frame.getContext()->m_ContextClass.get(); + _ContextClass = ctxt; + _totalMemoryID = frame.GetStaticMethodID(ctxt, "getTotalMemory", "()J"); + _freeMemoryID = frame.GetStaticMethodID(ctxt, "getFreeMemory", "()J"); + _maxMemoryID = frame.GetStaticMethodID(ctxt, "getMaxMemory", "()J"); + _usedMemoryID = frame.GetStaticMethodID(ctxt, "getUsedMemory", "()J"); + _heapMemoryID = frame.GetStaticMethodID(ctxt, "getHeapMemory", "()J"); + running = true; high_water = getWorkingSize(); limit = high_water + DELTA_LIMIT; @@ -237,10 +245,24 @@ void JPGarbageCollection::onEnd() Py_ssize_t pred = current + 2 * (current - last); last = current; if ((Py_ssize_t) pred > (Py_ssize_t) limit) + { run_gc = 2; + limit = high_water + (high_water>>3) + 8 * (current - last); + } - // printf("consider gc %d (%ld, %ld, %ld, %ld) %ld\n", run_gc, - // current, low_water, high_water, limit, limit - pred); +#if 0 + { + JPJavaFrame frame = JPJavaFrame::outer(m_Context); + jlong totalMemory = frame.CallStaticLongMethodA(_ContextClass, _totalMemoryID, nullptr); + jlong freeMemory = frame.CallStaticLongMethodA(_ContextClass, _freeMemoryID, nullptr); + jlong maxMemory = frame.CallStaticLongMethodA(_ContextClass, _maxMemoryID, nullptr); + jlong usedMemory = frame.CallStaticLongMethodA(_ContextClass, _usedMemoryID, nullptr); + jlong heapMemory = frame.CallStaticLongMethodA(_ContextClass, _heapMemoryID, nullptr); + printf("consider gc run=%d (current=%ld, low=%ld, high=%ld, limit=%ld) %ld\n", run_gc, + current, low_water, high_water, limit, limit - pred); + printf(" java total=%ld free=%ld max=%ld used=%ld heap=%ld\n", totalMemory, freeMemory, maxMemory, usedMemory, heapMemory); + } +#endif if (run_gc > 0) { diff --git a/native/java/org/jpype/JPypeContext.java b/native/java/org/jpype/JPypeContext.java index a2b039c75..ae0039566 100644 --- a/native/java/org/jpype/JPypeContext.java +++ b/native/java/org/jpype/JPypeContext.java @@ -637,4 +637,29 @@ private static void scanExistingJars() } } + private static long getTotalMemory() + { + return Runtime.getRuntime().totalMemory(); + } + + private static long getFreeMemory() + { + return Runtime.getRuntime().freeMemory(); + } + + private static long getMaxMemory() + { + return Runtime.getRuntime().maxMemory(); + } + + private static long getUsedMemory() + { + return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + } + + private static long getHeapMemory() + { + java.lang.management.MemoryMXBean memoryBean = java.lang.management.ManagementFactory.getMemoryMXBean(); + return memoryBean.getHeapMemoryUsage().getUsed(); + } } From b76471e85f9f93cc0d61ccbbd14142376f8abc9c Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 18:32:43 +0100 Subject: [PATCH 37/43] add twine check to sdist --- .azure/scripts/sdist.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.azure/scripts/sdist.yml b/.azure/scripts/sdist.yml index 2dda93e93..4a28ae5c3 100644 --- a/.azure/scripts/sdist.yml +++ b/.azure/scripts/sdist.yml @@ -3,9 +3,10 @@ steps: inputs: versionSpec: '3.10' - script: | - python -m pip install build + python -m pip install build twine python -m build ./ --sdist - displayName: Build sdist + twine check dist/* + displayName: Build sdist and check with twine - task: PublishPipelineArtifact@0 inputs: artifactName: 'artifact_SourceDistribution' From 16ef2f75071aa0b891784969a070d169b80dd581 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 18:43:47 +0100 Subject: [PATCH 38/43] add twine check to sdist and use it both in build and release pipelines --- .azure/release.yml | 2 ++ .azure/scripts/sdist.yml | 7 +++++++ .azure/scripts/test.yml | 6 ++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.azure/release.yml b/.azure/release.yml index 80d9a8e80..42d91288d 100644 --- a/.azure/release.yml +++ b/.azure/release.yml @@ -20,6 +20,8 @@ stages: vmImage: "ubuntu-latest" steps: - template: scripts/sdist.yml + parameters: + publish: true - template: scripts/ivy.yml - stage: Package diff --git a/.azure/scripts/sdist.yml b/.azure/scripts/sdist.yml index 4a28ae5c3..2f26b8aa7 100644 --- a/.azure/scripts/sdist.yml +++ b/.azure/scripts/sdist.yml @@ -1,3 +1,8 @@ +parameters: +- name: artifact + type: boolean + default: false + steps: - task: UsePythonVersion@0 inputs: @@ -7,7 +12,9 @@ steps: python -m build ./ --sdist twine check dist/* displayName: Build sdist and check with twine + - task: PublishPipelineArtifact@0 + condition: and(succeeded(), eq('${{ parameters.artifact }}', true)) inputs: artifactName: 'artifact_SourceDistribution' targetPath: 'dist' diff --git a/.azure/scripts/test.yml b/.azure/scripts/test.yml index a4e9bca41..d12fe806c 100644 --- a/.azure/scripts/test.yml +++ b/.azure/scripts/test.yml @@ -9,9 +9,11 @@ steps: parameters: version: '$(jdk.version)' +- template: sdist.yml + - script: | - python -m pip install -e .[test] - displayName: 'Build module' + python -m pip install dist/* + displayName: 'Install module from sdist' - script: | pip install numpy jedi typing_extensions From 9e597e4976d99048846e36f3c42d7ecac1dbdb0a Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 18:44:55 +0100 Subject: [PATCH 39/43] updated macos image to 13 (12 is deprecated) --- .azure/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure/build.yml b/.azure/build.yml index 805a3508b..1de334ebd 100644 --- a/.azure/build.yml +++ b/.azure/build.yml @@ -104,12 +104,12 @@ jobs: jdk.version: '21' # OSX, we only test an old Python version with JDK8 and recent Py with recent JDK. mac_py38_jdk8: - imageName: "macos-12" + imageName: "macos-13" python.version: '3.8' # todo: 3.8 will be EOL on October 31, 2024 jpypetest.fast: 'true' jdk.version: '8' mac_py312_jdk17: - imageName: "macos-12" + imageName: "macos-13" python.version: '3.12' jpypetest.fast: 'true' jdk.version: '17' From b93b0e0078cac1ec81120dfc7edc03ce421d248e Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 18:49:02 +0100 Subject: [PATCH 40/43] scaled logo to small version and use it readme --- README.rst | 3 +-- doc/logo_small.png | Bin 0 -> 45459 bytes 2 files changed, 1 insertion(+), 2 deletions(-) create mode 100644 doc/logo_small.png diff --git a/README.rst b/README.rst index 0e2ddab1c..01618319f 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,4 @@ -.. image:: doc/logo.png - :scale: 50 % +.. image:: doc/logo_small.png :alt: JPype logo :align: center diff --git a/doc/logo_small.png b/doc/logo_small.png new file mode 100644 index 0000000000000000000000000000000000000000..11dcdc292ed7b2e964df0f039d2d2e52bac48420 GIT binary patch literal 45459 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 PVgRy|iW0SA#v%U!?>sym literal 0 HcmV?d00001 From 50fa58dad36b73ae82ef4954e7fefb2eb019a720 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 19:13:16 +0100 Subject: [PATCH 41/43] testing from dist install does not work, use editable install again --- .azure/scripts/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure/scripts/test.yml b/.azure/scripts/test.yml index d12fe806c..ab34e1eb5 100644 --- a/.azure/scripts/test.yml +++ b/.azure/scripts/test.yml @@ -12,8 +12,8 @@ steps: - template: sdist.yml - script: | - python -m pip install dist/* - displayName: 'Install module from sdist' + python -m pip install -e . + displayName: 'Build/install module' - script: | pip install numpy jedi typing_extensions From 7c31d02df3f7abeadadf9307ebc8a959f2be2fb7 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 20:30:27 +0100 Subject: [PATCH 42/43] guard refcnt for nogil python --- native/common/jp_tracer.cpp | 8 +++++++- native/python/jp_pythontypes.cpp | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/native/common/jp_tracer.cpp b/native/common/jp_tracer.cpp index e6601f483..9f98dd15a 100644 --- a/native/common/jp_tracer.cpp +++ b/native/common/jp_tracer.cpp @@ -150,7 +150,13 @@ void JPypeTracer::tracePythonObject(const char* msg, PyObject* ref) if (ref != nullptr) { std::stringstream str; - str << msg << " " << (void*) ref << " " << Py_REFCNT(ref) << " " << Py_TYPE(ref)->tp_name; + str << msg << " " << (void*) ref << " "<< + #ifndef Py_GIL_DISABLED + Py_REFCNT(ref) + #else + -1 + #endif + << " " << Py_TYPE(ref)->tp_name; JPypeTracer::trace1("PY", str.str().c_str()); } else diff --git a/native/python/jp_pythontypes.cpp b/native/python/jp_pythontypes.cpp index dca3d2507..89c828023 100644 --- a/native/python/jp_pythontypes.cpp +++ b/native/python/jp_pythontypes.cpp @@ -22,6 +22,7 @@ static void assertValid(PyObject *obj) { +#ifndef Py_GIL_DISABLED if (Py_REFCNT(obj) >= 1) return; @@ -34,6 +35,9 @@ static void assertValid(PyObject *obj) JP_TRACE_PY("pyref FAULT", obj); JP_RAISE(PyExc_SystemError, "Deleted reference"); // GCOVR_EXCL_STOP +#else + return; // GIL is disabled; we assume obj is valid +#endif } /** From 98d7acf2b779e4f9a2f491a3f7145fa6b2da81e5 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 18 Nov 2024 20:46:20 +0100 Subject: [PATCH 43/43] fix param --- .azure/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/release.yml b/.azure/release.yml index 42d91288d..fa3bd04de 100644 --- a/.azure/release.yml +++ b/.azure/release.yml @@ -21,7 +21,7 @@ stages: steps: - template: scripts/sdist.yml parameters: - publish: true + artifact: true - template: scripts/ivy.yml - stage: Package