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' diff --git a/.azure/release.yml b/.azure/release.yml index b43d59fda..fa3bd04de 100644 --- a/.azure/release.yml +++ b/.azure/release.yml @@ -1,6 +1,6 @@ # JPype Release pipeline trigger: none -pr: +pr: branches: include: - releases/* @@ -10,16 +10,18 @@ pr: - .azure/release.yml variables: - package_name: JPype1 + package_name: jpype1 stages: - stage: Initial jobs: - job: SourceDistribution - pool: + pool: vmImage: "ubuntu-latest" steps: - template: scripts/sdist.yml + parameters: + artifact: true - template: scripts/ivy.yml - stage: Package @@ -27,23 +29,32 @@ stages: # From https://iscinumpy.gitlab.io/post/azure-devops-python-wheels/ - job: ManyLinux condition: eq(1,1) + timeoutInMinutes: 360 strategy: matrix: - # Disabled because it is fetching beta images - # 64Bit2014: - # arch: aarch64 - # plat: manylinux2014_aarch64 - # image: quay.io/pypa/manylinux2014_aarch64 - # python.architecture: aarch64 - 64Bit: + aarch64: + arch: aarch64 + 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 + 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 +# plat: musllinux_1_2 +# image: quay.io/pypa/musllinux_1_2_i686 python.architecture: x86 pool: vmImage: "ubuntu-latest" @@ -71,13 +82,17 @@ stages: Python312: python.version: '3.12' 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: @@ -101,8 +116,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)' 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 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 diff --git a/.azure/scripts/python.yml b/.azure/scripts/python.yml new file mode 100644 index 000000000..d99f23127 --- /dev/null +++ b/.azure/scripts/python.yml @@ -0,0 +1,21 @@ +parameters: +- name: version + type: string + default: '3.12' + +- name: architecture + type: string + default: 'x64' + +steps: + - task: UsePythonVersion@0 + inputs: + 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). + - bash: | + echo AGENT_JOBSTATUS = $AGENT_JOBSTATUS + if [[ "$AGENT_JOBSTATUS" == "SucceededWithIssues" ]]; then exit 1; fi + displayName: Python ${{ parameters.version }} set as interpreter. diff --git a/.azure/scripts/sdist.yml b/.azure/scripts/sdist.yml index ecf1fbe37..2f26b8aa7 100644 --- a/.azure/scripts/sdist.yml +++ b/.azure/scripts/sdist.yml @@ -1,12 +1,20 @@ +parameters: +- name: artifact + type: boolean + default: false + steps: - task: UsePythonVersion@0 inputs: - versionSpec: '3.8' + 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 + 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 660b9ae25..ab34e1eb5 100644 --- a/.azure/scripts/test.yml +++ b/.azure/scripts/test.yml @@ -1,20 +1,19 @@ # 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: version: '$(jdk.version)' +- template: sdist.yml + - script: | - python -m pip install setuptools - python setup.py develop - displayName: 'Build module' + python -m pip install -e . + displayName: 'Build/install module' - script: | pip install numpy jedi typing_extensions @@ -22,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' diff --git a/.azure/scripts/wheels-linux.yml b/.azure/scripts/wheels-linux.yml index b88b3948f..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.8' - task: DownloadPipelineArtifact@2 inputs: diff --git a/.azure/scripts/wheels.yml b/.azure/scripts/wheels.yml index 6d2790c14..8913f3fad 100644 --- a/.azure/scripts/wheels.yml +++ b/.azure/scripts/wheels.yml @@ -2,16 +2,12 @@ steps: - script: | mkdir -p dist - python -m pip install --upgrade pip + python -m pip install --upgrade pip setuptools -r test-requirements.txt displayName: 'Install dependencies' - script: | python -m pip wheel . -w wheelhouse/ displayName: 'Build wheel' - inputs: - PathtoPublish: 'wheelhouse' - ArtifactName: 'python-wheels' - publishLocation: 'Container' - script: | ls -lh wheelhouse @@ -19,20 +15,25 @@ 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: | python setup.py test_java - python -m pip install -r test-requirements.txt - displayName: 'Install test' + displayName: 'Build java tests' - script: | ls -l ls lib/ displayName: 'Check deps' +- task: PublishPipelineArtifact@0 + inputs: + artifactName: 'artifact_$(Agent.JobName)_$(Agent.OS)_$(python.architecture)' + targetPath: 'dist' + - script: | + rm -Rf jpype python -m pytest -v --junit-xml=build/test/test.xml test/jpypetest --checkjni --fast displayName: 'Test module' diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 456d45728..8f0d430da 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,10 +1,10 @@ [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+))? +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/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/CHANGELOG.rst b/doc/CHANGELOG.rst index dd61866c7..990befdd3 100644 --- a/doc/CHANGELOG.rst +++ b/doc/CHANGELOG.rst @@ -4,8 +4,11 @@ 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** + - Future proofing for Python 3.14 + + - Support for Python 3.13 - Allow access to default methods implemented in interfaces when using ``@JImplements``. diff --git a/doc/logo_small.png b/doc/logo_small.png new file mode 100644 index 000000000..11dcdc292 Binary files /dev/null and b/doc/logo_small.png differ diff --git a/jpype/__init__.py b/jpype/__init__.py index c17f43065..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/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); 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/java/org/jpype/JPypeContext.java b/native/java/org/jpype/JPypeContext.java index 0d5aacca5..ae0039566 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/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 } /** diff --git a/native/python/pyjp_module.cpp b/native/python/pyjp_module.cpp index 0b04e33e1..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 f35392751..72f10b945 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,8 +6,8 @@ build-backend = "setuptools.build_meta" [project] -name = "JPype1" -version = '1.5.0.dev0' +name = "jpype1" +version = '1.5.1' authors = [ {name = "Steve Menard", email = "devilwolf@users.sourceforge.net"}, ] @@ -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"', ]