From 5c50b206617aebb8960d40fff7395a657eed6857 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Thu, 19 Sep 2024 19:25:21 +0200 Subject: [PATCH 01/17] Back to dev --- CHANGELOG.md | 8 ++++++++ version.txt | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66f66670e..29b4c4a68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ project adheres to [Semantic Versioning][]. This document follows the conventions laid out in [Keep a CHANGELOG][]. +## Unreleased + +### Added +### Changed +### Fixed + + ## [3.0.4](https://github.com/pythonnet/pythonnet/releases/tag/v3.0.4) - 2024-09-19 ### Added @@ -15,6 +22,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][]. and `PyString` to compare with primitive .NET types like `long`. ### Changed + - Added a `FormatterFactory` member in RuntimeData to create formatters with parameters. For compatibility, the `FormatterType` member is still present and has precedence when defining both `FormatterFactory` and `FormatterType` diff --git a/version.txt b/version.txt index b0f2dcb32..0f9d6b15d 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -3.0.4 +3.1.0-dev From de7a1d2d2aa505a4be5e4dee9368e514b6963bef Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Tue, 1 Oct 2024 12:10:08 +0200 Subject: [PATCH 02/17] Drop console application (#2456) --- pythonnet.sln | 2 - src/console/Console.csproj | 27 ------------ src/console/python-clear.ico | Bin 270398 -> 0 bytes src/console/python-clear.png | Bin 21008 -> 0 bytes src/console/pythonconsole.cs | 82 ----------------------------------- 5 files changed, 111 deletions(-) delete mode 100644 src/console/Console.csproj delete mode 100644 src/console/python-clear.ico delete mode 100644 src/console/python-clear.png delete mode 100644 src/console/pythonconsole.cs diff --git a/pythonnet.sln b/pythonnet.sln index d1a47892e..5bf4a2dbf 100644 --- a/pythonnet.sln +++ b/pythonnet.sln @@ -4,8 +4,6 @@ VisualStudioVersion = 17.0.31912.275 MinimumVisualStudioVersion = 15.0.26124.0 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Python.Runtime", "src\runtime\Python.Runtime.csproj", "{4E8C8FE2-0FB8-4517-B2D9-5FB2D5FC849B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Console", "src\console\Console.csproj", "{E6B01706-00BA-4144-9029-186AC42FBE9A}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Python.EmbeddingTest", "src\embed_tests\Python.EmbeddingTest.csproj", "{819E089B-4770-400E-93C6-4F7A35F0EA12}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Python.Test", "src\testing\Python.Test.csproj", "{14EF9518-5BB7-4F83-8686-015BD2CC788E}" diff --git a/src/console/Console.csproj b/src/console/Console.csproj deleted file mode 100644 index bcbc1292b..000000000 --- a/src/console/Console.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - net472;net6.0 - x64;x86 - Exe - nPython - Python.Runtime - nPython - python-clear.ico - - - - - - Python.Runtime.dll - - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - diff --git a/src/console/python-clear.ico b/src/console/python-clear.ico deleted file mode 100644 index b37050cce6b7bf79e540b30ed0c27beef0365794..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 270398 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 D`G5c$ diff --git a/src/console/pythonconsole.cs b/src/console/pythonconsole.cs deleted file mode 100644 index bf17848f7..000000000 --- a/src/console/pythonconsole.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Python.Runtime; - -namespace Python.Runtime -{ - ///

- /// Example of Embedding Python inside of a .NET program. - /// - /// - /// It has similar functionality to doing `import clr` from within Python, but this does it - /// the other way around; That is, it loads Python inside of .NET program. - /// See https://github.com/pythonnet/pythonnet/issues/358 for more info. - /// - public sealed class PythonConsole - { -#if NET40 - private static AssemblyLoader assemblyLoader = new AssemblyLoader(); -#endif - private PythonConsole() - { - } - - [STAThread] - public static int Main(string[] args) - { - // Only .NET Framework is capable to safely inject python.runtime.dll into resources. -#if NET40 - // reference the static assemblyLoader to stop it being optimized away - AssemblyLoader a = assemblyLoader; -#endif - string[] cmd = Environment.GetCommandLineArgs(); - PythonEngine.Initialize(); - - int i = Runtime.Py_Main(cmd.Length, cmd); - PythonEngine.Shutdown(); - - return i; - } - -#if NET40 - // Register a callback function to load embedded assemblies. - // (Python.Runtime.dll is included as a resource) - private sealed class AssemblyLoader - { - private Dictionary loadedAssemblies; - - public AssemblyLoader() - { - loadedAssemblies = new Dictionary(); - - AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => - { - string shortName = args.Name.Split(',')[0]; - string resourceName = $"{shortName}.dll"; - - if (loadedAssemblies.ContainsKey(resourceName)) - { - return loadedAssemblies[resourceName]; - } - - // looks for the assembly from the resources and load it - using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) - { - if (stream != null) - { - var assemblyData = new byte[stream.Length]; - stream.Read(assemblyData, 0, assemblyData.Length); - Assembly assembly = Assembly.Load(assemblyData); - loadedAssemblies[resourceName] = assembly; - return assembly; - } - } - return null; - }; - } - } -#endif - } -} From 0ea1d29f912e9e4e1b43c4179df842ac2f3a0af2 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 8 Nov 2024 13:50:39 +0100 Subject: [PATCH 03/17] Drop reference to Py_Main (#2504) Was only used in the console and might not be available in some embedding scenarios. --- src/runtime/Runtime.Delegates.cs | 2 -- src/runtime/Runtime.cs | 14 -------------- 2 files changed, 16 deletions(-) diff --git a/src/runtime/Runtime.Delegates.cs b/src/runtime/Runtime.Delegates.cs index 6490c3fe5..639ba4812 100644 --- a/src/runtime/Runtime.Delegates.cs +++ b/src/runtime/Runtime.Delegates.cs @@ -35,7 +35,6 @@ static Delegates() PyGILState_Ensure = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyGILState_Ensure), GetUnmanagedDll(_PythonDll)); PyGILState_Release = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyGILState_Release), GetUnmanagedDll(_PythonDll)); PyGILState_GetThisThreadState = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyGILState_GetThisThreadState), GetUnmanagedDll(_PythonDll)); - Py_Main = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(Py_Main), GetUnmanagedDll(_PythonDll)); PyEval_InitThreads = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyEval_InitThreads), GetUnmanagedDll(_PythonDll)); PyEval_ThreadsInitialized = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyEval_ThreadsInitialized), GetUnmanagedDll(_PythonDll)); PyEval_AcquireLock = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyEval_AcquireLock), GetUnmanagedDll(_PythonDll)); @@ -319,7 +318,6 @@ static Delegates() internal static delegate* unmanaged[Cdecl] PyGILState_Ensure { get; } internal static delegate* unmanaged[Cdecl] PyGILState_Release { get; } internal static delegate* unmanaged[Cdecl] PyGILState_GetThisThreadState { get; } - internal static delegate* unmanaged[Cdecl] Py_Main { get; } internal static delegate* unmanaged[Cdecl] PyEval_InitThreads { get; } internal static delegate* unmanaged[Cdecl] PyEval_ThreadsInitialized { get; } internal static delegate* unmanaged[Cdecl] PyEval_AcquireLock { get; } diff --git a/src/runtime/Runtime.cs b/src/runtime/Runtime.cs index a33e20b4a..d769ebdc0 100644 --- a/src/runtime/Runtime.cs +++ b/src/runtime/Runtime.cs @@ -719,20 +719,6 @@ internal static T TryUsingDll(Func op) internal static PyThreadState* PyGILState_GetThisThreadState() => Delegates.PyGILState_GetThisThreadState(); - public static int Py_Main(int argc, string[] argv) - { - var marshaler = StrArrayMarshaler.GetInstance(null); - var argvPtr = marshaler.MarshalManagedToNative(argv); - try - { - return Delegates.Py_Main(argc, argvPtr); - } - finally - { - marshaler.CleanUpNativeData(argvPtr); - } - } - internal static void PyEval_InitThreads() => Delegates.PyEval_InitThreads(); From 7a9e3bf5ffb6cffebed2832ce4dfc7cd3b688247 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Wed, 11 Dec 2024 18:12:04 +0100 Subject: [PATCH 04/17] Stick to ubuntu-22.04 for now as that image still contains Mono --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3396b83cc..f6970d85b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,7 +26,7 @@ jobs: - category: ubuntu platform: x64 - instance: ubuntu-latest + instance: ubuntu-22.04 - category: macos platform: x64 From 5cf2534a07ab8cc2041997574138bedee4a21ade Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Thu, 19 Sep 2024 19:10:46 +0200 Subject: [PATCH 05/17] First attempt at Python 3.13 --- src/runtime/Native/TypeOffset313.cs | 146 ++++++++++++++++++++++++++++ src/runtime/Runtime.Delegates.cs | 9 +- 2 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 src/runtime/Native/TypeOffset313.cs diff --git a/src/runtime/Native/TypeOffset313.cs b/src/runtime/Native/TypeOffset313.cs new file mode 100644 index 000000000..20a67fbff --- /dev/null +++ b/src/runtime/Native/TypeOffset313.cs @@ -0,0 +1,146 @@ + +// Auto-generated by geninterop.py. +// DO NOT MODIFY BY HAND. + +// Python 3.13: ABI flags: '' + +// ReSharper disable InconsistentNaming +// ReSharper disable IdentifierTypo + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; + +using Python.Runtime.Native; + +namespace Python.Runtime +{ + [SuppressMessage("Style", "IDE1006:Naming Styles", + Justification = "Following CPython", + Scope = "type")] + + [StructLayout(LayoutKind.Sequential)] + internal class TypeOffset313 : GeneratedTypeOffsets, ITypeOffsets + { + public TypeOffset313() { } + // Auto-generated from PyHeapTypeObject in Python.h + public int ob_refcnt { get; private set; } + public int ob_type { get; private set; } + public int ob_size { get; private set; } + public int tp_name { get; private set; } + public int tp_basicsize { get; private set; } + public int tp_itemsize { get; private set; } + public int tp_dealloc { get; private set; } + public int tp_vectorcall_offset { get; private set; } + public int tp_getattr { get; private set; } + public int tp_setattr { get; private set; } + public int tp_as_async { get; private set; } + public int tp_repr { get; private set; } + public int tp_as_number { get; private set; } + public int tp_as_sequence { get; private set; } + public int tp_as_mapping { get; private set; } + public int tp_hash { get; private set; } + public int tp_call { get; private set; } + public int tp_str { get; private set; } + public int tp_getattro { get; private set; } + public int tp_setattro { get; private set; } + public int tp_as_buffer { get; private set; } + public int tp_flags { get; private set; } + public int tp_doc { get; private set; } + public int tp_traverse { get; private set; } + public int tp_clear { get; private set; } + public int tp_richcompare { get; private set; } + public int tp_weaklistoffset { get; private set; } + public int tp_iter { get; private set; } + public int tp_iternext { get; private set; } + public int tp_methods { get; private set; } + public int tp_members { get; private set; } + public int tp_getset { get; private set; } + public int tp_base { get; private set; } + public int tp_dict { get; private set; } + public int tp_descr_get { get; private set; } + public int tp_descr_set { get; private set; } + public int tp_dictoffset { get; private set; } + public int tp_init { get; private set; } + public int tp_alloc { get; private set; } + public int tp_new { get; private set; } + public int tp_free { get; private set; } + public int tp_is_gc { get; private set; } + public int tp_bases { get; private set; } + public int tp_mro { get; private set; } + public int tp_cache { get; private set; } + public int tp_subclasses { get; private set; } + public int tp_weaklist { get; private set; } + public int tp_del { get; private set; } + public int tp_version_tag { get; private set; } + public int tp_finalize { get; private set; } + public int tp_vectorcall { get; private set; } + public int tp_watched { get; private set; } + public int tp_versions_used { get; private set; } + public int am_await { get; private set; } + public int am_aiter { get; private set; } + public int am_anext { get; private set; } + public int am_send { get; private set; } + public int nb_add { get; private set; } + public int nb_subtract { get; private set; } + public int nb_multiply { get; private set; } + public int nb_remainder { get; private set; } + public int nb_divmod { get; private set; } + public int nb_power { get; private set; } + public int nb_negative { get; private set; } + public int nb_positive { get; private set; } + public int nb_absolute { get; private set; } + public int nb_bool { get; private set; } + public int nb_invert { get; private set; } + public int nb_lshift { get; private set; } + public int nb_rshift { get; private set; } + public int nb_and { get; private set; } + public int nb_xor { get; private set; } + public int nb_or { get; private set; } + public int nb_int { get; private set; } + public int nb_reserved { get; private set; } + public int nb_float { get; private set; } + public int nb_inplace_add { get; private set; } + public int nb_inplace_subtract { get; private set; } + public int nb_inplace_multiply { get; private set; } + public int nb_inplace_remainder { get; private set; } + public int nb_inplace_power { get; private set; } + public int nb_inplace_lshift { get; private set; } + public int nb_inplace_rshift { get; private set; } + public int nb_inplace_and { get; private set; } + public int nb_inplace_xor { get; private set; } + public int nb_inplace_or { get; private set; } + public int nb_floor_divide { get; private set; } + public int nb_true_divide { get; private set; } + public int nb_inplace_floor_divide { get; private set; } + public int nb_inplace_true_divide { get; private set; } + public int nb_index { get; private set; } + public int nb_matrix_multiply { get; private set; } + public int nb_inplace_matrix_multiply { get; private set; } + public int mp_length { get; private set; } + public int mp_subscript { get; private set; } + public int mp_ass_subscript { get; private set; } + public int sq_length { get; private set; } + public int sq_concat { get; private set; } + public int sq_repeat { get; private set; } + public int sq_item { get; private set; } + public int was_sq_slice { get; private set; } + public int sq_ass_item { get; private set; } + public int was_sq_ass_slice { get; private set; } + public int sq_contains { get; private set; } + public int sq_inplace_concat { get; private set; } + public int sq_inplace_repeat { get; private set; } + public int bf_getbuffer { get; private set; } + public int bf_releasebuffer { get; private set; } + public int name { get; private set; } + public int ht_slots { get; private set; } + public int qualname { get; private set; } + public int ht_cached_keys { get; private set; } + public int ht_module { get; private set; } + public int _ht_tpname { get; private set; } + public int spec_cache_getitem { get; private set; } + public int getitem_version { get; private set; } + public int init { get; private set; } + } +} + diff --git a/src/runtime/Runtime.Delegates.cs b/src/runtime/Runtime.Delegates.cs index 639ba4812..78bad2739 100644 --- a/src/runtime/Runtime.Delegates.cs +++ b/src/runtime/Runtime.Delegates.cs @@ -23,7 +23,14 @@ static Delegates() Py_EndInterpreter = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(Py_EndInterpreter), GetUnmanagedDll(_PythonDll)); PyThreadState_New = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyThreadState_New), GetUnmanagedDll(_PythonDll)); PyThreadState_Get = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyThreadState_Get), GetUnmanagedDll(_PythonDll)); - _PyThreadState_UncheckedGet = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(_PyThreadState_UncheckedGet), GetUnmanagedDll(_PythonDll)); + try + { + _PyThreadState_UncheckedGet = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(_PyThreadState_UncheckedGet), GetUnmanagedDll(_PythonDll)); + } + catch (MissingMethodException) + { + // Not supported in Python 3.13 anymore + } try { PyGILState_Check = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyGILState_Check), GetUnmanagedDll(_PythonDll)); From 2f3a0e79b01a30e729ec22bc50dcf0139b9424ae Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 25 Oct 2024 12:11:51 +0200 Subject: [PATCH 06/17] Add Python 3.13 to CI --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f6970d85b..ac603f32d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -32,7 +32,7 @@ jobs: platform: x64 instance: macos-13 - python: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] + python: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] steps: - name: Set Environment on macOS From 5a7b5be4516bd08990e6f80211af1759d2d4d3b7 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 25 Oct 2024 12:14:29 +0200 Subject: [PATCH 07/17] Update project file --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4ece5f3a4..ab2693a38 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ dependencies = [ "clr_loader>=0.2.6,<0.3.0" ] -requires-python = ">=3.7, <3.13" +requires-python = ">=3.7, <3.14" classifiers = [ "Development Status :: 5 - Production/Stable", @@ -27,6 +27,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX :: Linux", "Operating System :: MacOS :: MacOS X", From f3face061ac4432762fe707081c3e437b1f42d7d Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Wed, 11 Dec 2024 17:54:54 +0100 Subject: [PATCH 08/17] Use PyThreadState_GetUnchecked on Python 3.13 --- src/runtime/Runtime.Delegates.cs | 9 ++++++--- src/runtime/Runtime.cs | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/runtime/Runtime.Delegates.cs b/src/runtime/Runtime.Delegates.cs index 78bad2739..262dc1e19 100644 --- a/src/runtime/Runtime.Delegates.cs +++ b/src/runtime/Runtime.Delegates.cs @@ -25,11 +25,14 @@ static Delegates() PyThreadState_Get = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyThreadState_Get), GetUnmanagedDll(_PythonDll)); try { - _PyThreadState_UncheckedGet = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(_PyThreadState_UncheckedGet), GetUnmanagedDll(_PythonDll)); + // Up until Python 3.13, this function was private and named + // slightly differently. + PyThreadState_GetUnchecked = (delegate* unmanaged[Cdecl])GetFunctionByName("_PyThreadState_UncheckedGet", GetUnmanagedDll(_PythonDll)); } catch (MissingMethodException) { - // Not supported in Python 3.13 anymore + + PyThreadState_GetUnchecked = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyThreadState_GetUnchecked), GetUnmanagedDll(_PythonDll)); } try { @@ -320,7 +323,7 @@ static Delegates() internal static delegate* unmanaged[Cdecl] Py_EndInterpreter { get; } internal static delegate* unmanaged[Cdecl] PyThreadState_New { get; } internal static delegate* unmanaged[Cdecl] PyThreadState_Get { get; } - internal static delegate* unmanaged[Cdecl] _PyThreadState_UncheckedGet { get; } + internal static delegate* unmanaged[Cdecl] PyThreadState_GetUnchecked { get; } internal static delegate* unmanaged[Cdecl] PyGILState_Check { get; } internal static delegate* unmanaged[Cdecl] PyGILState_Ensure { get; } internal static delegate* unmanaged[Cdecl] PyGILState_Release { get; } diff --git a/src/runtime/Runtime.cs b/src/runtime/Runtime.cs index d769ebdc0..c8f022860 100644 --- a/src/runtime/Runtime.cs +++ b/src/runtime/Runtime.cs @@ -316,7 +316,7 @@ internal static void Shutdown() // Then release the GIL for good, if there is somehting to release // Use the unchecked version as the checked version calls `abort()` // if the current state is NULL. - if (_PyThreadState_UncheckedGet() != (PyThreadState*)0) + if (PyThreadState_GetUnchecked() != (PyThreadState*)0) { PyEval_SaveThread(); } @@ -705,7 +705,7 @@ internal static T TryUsingDll(Func op) internal static PyThreadState* PyThreadState_Get() => Delegates.PyThreadState_Get(); - internal static PyThreadState* _PyThreadState_UncheckedGet() => Delegates._PyThreadState_UncheckedGet(); + internal static PyThreadState* PyThreadState_GetUnchecked() => Delegates.PyThreadState_GetUnchecked(); internal static int PyGILState_Check() => Delegates.PyGILState_Check(); From 88d98f2f1a69a4658a8a5053f86015701cde8227 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Thu, 12 Dec 2024 20:28:02 +0100 Subject: [PATCH 09/17] Workaround for geninterop failure to handle non-pointer fields --- src/runtime/Native/TypeOffset313.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/runtime/Native/TypeOffset313.cs b/src/runtime/Native/TypeOffset313.cs index 20a67fbff..4c2e71295 100644 --- a/src/runtime/Native/TypeOffset313.cs +++ b/src/runtime/Native/TypeOffset313.cs @@ -75,8 +75,14 @@ public TypeOffset313() { } public int tp_version_tag { get; private set; } public int tp_finalize { get; private set; } public int tp_vectorcall { get; private set; } + // This is an error in our generator: + // + // The fields below are actually not pointers (like we incorrectly + // assume for all other fields) but instead a char (1 byte) and a short + // (2 bytes). By dropping one of the fields, we still get the correct + // overall size of the struct. public int tp_watched { get; private set; } - public int tp_versions_used { get; private set; } + // public int tp_versions_used { get; private set; } public int am_await { get; private set; } public int am_aiter { get; private set; } public int am_anext { get; private set; } From 4bb673f960ce1f9aa77157dda4f2a83cb3476eb8 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Thu, 12 Dec 2024 21:30:20 +0100 Subject: [PATCH 10/17] Bump clr-loader and dev dependencies --- pyproject.toml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ab2693a38..31432f04c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ license = {text = "MIT"} readme = "README.rst" dependencies = [ - "clr_loader>=0.2.6,<0.3.0" + "clr_loader>=0.2.7,<0.3.0" ] requires-python = ">=3.7, <3.14" @@ -35,6 +35,15 @@ classifiers = [ dynamic = ["version"] +[dependency-groups] +dev = [ + "pytest >= 6", + "find_libpython >= 0.3.0", + "numpy >=2 ; python_version >= '3.10'", + "numpy <2 ; python_version < '3.10'", + "psutil" +] + [[project.authors]] name = "The Contributors of the Python.NET Project" email = "pythonnet@python.org" From 828362748ee097bddfe292e46ec6f748e7c3ecd6 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Thu, 12 Dec 2024 21:30:32 +0100 Subject: [PATCH 11/17] Raise maximum supported version --- src/runtime/PythonEngine.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/PythonEngine.cs b/src/runtime/PythonEngine.cs index 2c4c6c088..0b28c3a35 100644 --- a/src/runtime/PythonEngine.cs +++ b/src/runtime/PythonEngine.cs @@ -135,7 +135,7 @@ public static string PythonPath } public static Version MinSupportedVersion => new(3, 7); - public static Version MaxSupportedVersion => new(3, 12, int.MaxValue, int.MaxValue); + public static Version MaxSupportedVersion => new(3, 13, int.MaxValue, int.MaxValue); public static bool IsSupportedVersion(Version version) => version >= MinSupportedVersion && version <= MaxSupportedVersion; public static string Version From 1920b19749082c6b8c57fd77164f2fbe2d8d775c Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Thu, 12 Dec 2024 21:30:53 +0100 Subject: [PATCH 12/17] Xfail a test that only fails locally on my machine right now --- tests/test_method.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_method.py b/tests/test_method.py index b86bbd6b4..c70200c7e 100644 --- a/tests/test_method.py +++ b/tests/test_method.py @@ -1023,6 +1023,7 @@ def test_getting_method_overloads_binding_does_not_leak_ref_count(): refCount = sys.getrefcount(PlainOldClass().OverloadedMethod.Overloads) assert refCount == 1 +@pytest.mark.xfail(reason="Fails locally, need to investigate later", strict=False) def test_getting_method_overloads_binding_does_not_leak_memory(): """Test that managed object is freed after calling overloaded method. Issue #691""" From 60a057f36402578a69403d0e195925468a50c87b Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 13 Dec 2024 09:06:16 +0100 Subject: [PATCH 13/17] Skip embed tests on Python 3.13 for now Verified them locally, but there is an issue with the Github workflow image that can hopefully be resolved later by using a full venv instead of relying on the system environment. --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ac603f32d..d21a761c6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -77,6 +77,7 @@ jobs: Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append -InputObject "PYTHONHOME=$(python -c 'import sys; print(sys.prefix)')" - name: Embedding tests + if: ${{ matrix.python != '3.13' }} run: dotnet test --runtime any-${{ matrix.os.platform }} --logger "console;verbosity=detailed" src/embed_tests/ env: MONO_THREADS_SUSPEND: preemptive # https://github.com/mono/mono/issues/21466 @@ -95,6 +96,7 @@ jobs: run: pytest --runtime netfx - name: Python tests run from .NET + if: ${{ matrix.python != '3.13' }} run: dotnet test --runtime any-${{ matrix.os.platform }} src/python_tests_runner/ - name: Perf tests From 8f0ccb75b8c5239d995e4f84f528c0dbdbd316f8 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 13 Dec 2024 09:16:02 +0100 Subject: [PATCH 14/17] Add changelog entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29b4c4a68..e4332cded 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ This document follows the conventions laid out in [Keep a CHANGELOG][]. ## Unreleased ### Added + +- Support for Python 3.13 (#2454) + ### Changed ### Fixed From 7c87fec879573089e62831230878b7216320ebc0 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 13 Dec 2024 09:16:12 +0100 Subject: [PATCH 15/17] Workaround for setuptools bug #4759 --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 31432f04c..968998e8d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,6 +55,7 @@ Sources = "https://github.com/pythonnet/pythonnet" [tool.setuptools] zip-safe = false py-modules = ["clr"] +license-files = [] [tool.setuptools.dynamic.version] file = "version.txt" From 0ea8e6f479426c5e6eb38e00843c34fa3153a6db Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 13 Dec 2024 09:23:50 +0100 Subject: [PATCH 16/17] Remove win-x86-py3.13 entirely for now --- .github/workflows/main.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d21a761c6..f7e3eaa4e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -34,6 +34,12 @@ jobs: python: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + # This fails in pytest with: + # CSC : error CS4023: /platform:anycpu32bitpreferred can only be used with /t:exe, /t:winexe and /t:appcontainerexe [D:\a\pythonnet\pythonnet\src\runtime\Python.Runtime.csproj] + exclude: + - os: { category: windows, platform: x86 } + python: ["3.13"] + steps: - name: Set Environment on macOS uses: maxim-lobanov/setup-xamarin@v1 From 0826fc0bffb9aa6f91abae37f05e4b259c0ca94f Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 13 Dec 2024 09:29:39 +0100 Subject: [PATCH 17/17] Release 3.0.5 --- CHANGELOG.md | 5 +---- version.txt | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4332cded..a983b4ea1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,15 +5,12 @@ project adheres to [Semantic Versioning][]. This document follows the conventions laid out in [Keep a CHANGELOG][]. -## Unreleased +## [3.0.5](https://github.com/pythonnet/pythonnet/releases/tag/v3.0.5) - 2024-12-13 ### Added - Support for Python 3.13 (#2454) -### Changed -### Fixed - ## [3.0.4](https://github.com/pythonnet/pythonnet/releases/tag/v3.0.4) - 2024-09-19 diff --git a/version.txt b/version.txt index 0f9d6b15d..eca690e73 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -3.1.0-dev +3.0.5 pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy