diff --git a/.editorconfig b/.editorconfig
index f7658ff73..4a7fd19de 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -95,6 +95,7 @@ dotnet_diagnostic.CA2211.severity = none # CA2211: Non-constant fields sh
dotnet_diagnostic.CA2219.severity = suggestion # CA2219: Do not raise exceptions in finally clauses
dotnet_diagnostic.CA2229.severity = suggestion # CA2229: Implement serialization constructors
dotnet_diagnostic.CA2249.severity = suggestion # CA2249: Consider using 'string.Contains' instead of 'string.IndexOf'
+dotnet_diagnostic.CA2263.severity = none # CA2263: Prefer generic overload when type is known
dotnet_diagnostic.CA3075.severity = suggestion # CA3075: Insecure DTD processing in XML
dotnet_diagnostic.CA5350.severity = suggestion # CA5350: Do Not Use Weak Cryptographic Algorithms
dotnet_diagnostic.CA5351.severity = suggestion # CA5351: Do Not Use Broken Cryptographic Algorithms
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index e44d936df..e43e3cf9b 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -21,18 +21,22 @@ jobs:
submodules: true
# Setup .NET
- - name: Setup .NET 6.0
+ - name: Setup .NET 10.0
uses: actions/setup-dotnet@v4
with:
- dotnet-version: '6.0.x'
+ dotnet-version: '10.0.x'
+ - name: Setup .NET 9.0
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: '9.0.x'
- name: Setup .NET 8.0
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- - name: Setup .NET 9.0
+ - name: Setup .NET 6.0
uses: actions/setup-dotnet@v4
with:
- dotnet-version: '9.0.x'
+ dotnet-version: '6.0.x'
# CI debug information
- name: Version Information
@@ -61,7 +65,7 @@ jobs:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-22.04, macos-14]
- framework: ['net462', 'net6.0', 'net8.0']
+ framework: ['net462', 'net6.0', 'net8.0', 'net10.0']
steps:
# Prerequisites
@@ -70,18 +74,22 @@ jobs:
submodules: true
# Setup .NET
- - name: Setup .NET 6.0
+ - name: Setup .NET 10.0
uses: actions/setup-dotnet@v4
with:
- dotnet-version: '6.0.x'
+ dotnet-version: '10.0.x'
+ - name: Setup .NET 9.0
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: '9.0.x'
- name: Setup .NET 8.0
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- - name: Setup .NET 9.0
+ - name: Setup .NET 6.0
uses: actions/setup-dotnet@v4
with:
- dotnet-version: '9.0.x'
+ dotnet-version: '6.0.x'
# Build & Test
- name: Build
diff --git a/.vsts-ci.yml b/.vsts-ci.yml
index 98ff4c5fb..14a5acb2a 100644
--- a/.vsts-ci.yml
+++ b/.vsts-ci.yml
@@ -120,6 +120,18 @@ jobs:
osName: Windows
imageName: windows-latest
framework: net8.0
+ linux_net10_0:
+ osName: Linux
+ imageName: ubuntu-22.04
+ framework: net10.0
+ macos_net10_0:
+ osName: macOS
+ imageName: macOS-14
+ framework: net10.0
+ windows_net10_0:
+ osName: Windows
+ imageName: windows-latest
+ framework: net10.0
displayName: Test
timeoutInMinutes: 180
diff --git a/IronPython.sln b/IronPython.sln
index 2a77b6b94..d4427d78c 100644
--- a/IronPython.sln
+++ b/IronPython.sln
@@ -41,6 +41,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{17737ACB
eng\net8.0.props = eng\net8.0.props
eng\net9.0-windows.props = eng\net9.0-windows.props
eng\net9.0.props = eng\net9.0.props
+ eng\net10.0-windows.props = eng\net10.0-windows.props
+ eng\net10.0.props = eng\net10.0.props
eng\netstandard2.0.props = eng\netstandard2.0.props
eng\Tasks.Targets = eng\Tasks.Targets
EndProjectSection
diff --git a/README.md b/README.md
index 44353a451..62f95d27d 100644
--- a/README.md
+++ b/README.md
@@ -152,4 +152,4 @@ See the [building document](https://github.com/IronLanguages/ironpython3/wiki/Bu
## Supported Platforms
-IronPython 3 targets .NET Framework 4.6.2, .NET Standard 2.0, .NET 6.0 and .NET 8.0. The support for .NET and .NET Core follow the lifecycle defined on [.NET and .NET Core Support Policy](https://dotnet.microsoft.com/platform/support/policy/dotnet-core).
+IronPython 3 targets .NET Framework 4.6.2, .NET Standard 2.0, .NET 6.0, .NET 8.0, and .NET 10.0. The support for .NET and .NET Core follow the lifecycle defined on [.NET and .NET Core Support Policy](https://dotnet.microsoft.com/platform/support/policy/dotnet-core).
diff --git a/eng/net10.0-windows.props b/eng/net10.0-windows.props
new file mode 100644
index 000000000..821e22cdc
--- /dev/null
+++ b/eng/net10.0-windows.props
@@ -0,0 +1,9 @@
+
+
+ false
+ $(BaseIntermediateOutputPath)$(Configuration)\net10.0
+ $(BaseOutputPath)\net10.0
+
+
+
+
diff --git a/eng/net10.0.props b/eng/net10.0.props
new file mode 100644
index 000000000..926dadc14
--- /dev/null
+++ b/eng/net10.0.props
@@ -0,0 +1,38 @@
+
+
+
+ false
+
+
+
+ $(Features);FEATURE_APARTMENTSTATE
+ $(Features);FEATURE_ASSEMBLY_GETFORWARDEDTYPES
+ $(Features);FEATURE_ASSEMBLY_RESOLVE
+ $(Features);FEATURE_ASSEMBLYBUILDER_DEFINEDYNAMICASSEMBLY
+ $(Features);FEATURE_CODEDOM
+ $(Features);FEATURE_COM
+ $(Features);FEATURE_CONFIGURATION
+ $(Features);FEATURE_CTYPES
+ $(Features);FEATURE_CUSTOM_TYPE_DESCRIPTOR
+ $(Features);FEATURE_EXCEPTION_STATE
+ $(Features);FEATURE_FILESYSTEM
+ $(Features);FEATURE_FULL_CRYPTO
+ $(Features);FEATURE_FULL_NET
+ $(Features);FEATURE_LCG
+ $(Features);FEATURE_LOADWITHPARTIALNAME
+ $(Features);FEATURE_METADATA_READER
+ $(Features);FEATURE_MMAP
+ $(Features);FEATURE_NATIVE
+ $(Features);FEATURE_OSPLATFORMATTRIBUTE
+ $(Features);FEATURE_PIPES
+ $(Features);FEATURE_PROCESS
+ $(Features);FEATURE_REFEMIT
+ $(Features);FEATURE_REGISTRY
+ $(Features);FEATURE_RUNTIMEINFORMATION
+ $(Features);FEATURE_SECURITY_RULES
+ $(Features);FEATURE_STACK_TRACE
+ $(Features);FEATURE_SYNC_SOCKETS
+ $(Features);FEATURE_THREAD
+ $(Features);FEATURE_XMLDOC
+
+
diff --git a/eng/package/nuget/IronPython.nuspec b/eng/package/nuget/IronPython.nuspec
index 1c3b0e0cd..5aaf7f951 100644
--- a/eng/package/nuget/IronPython.nuspec
+++ b/eng/package/nuget/IronPython.nuspec
@@ -33,6 +33,10 @@ This package contains the IronPython interpreter engine.
+
+
+
+
diff --git a/make.ps1 b/make.ps1
index 16c41b673..bcf210273 100755
--- a/make.ps1
+++ b/make.ps1
@@ -4,7 +4,7 @@ Param(
[Parameter(Position=1)]
[String] $target = "build",
[String] $configuration = "Release",
- [String[]] $frameworks=@('net462','net6.0','net8.0'),
+ [String[]] $frameworks=@('net462','net6.0','net8.0','net10.0'),
[String] $platform = $null, # auto-detect
[switch] $runIgnored,
[int] $jobs = [System.Environment]::ProcessorCount
diff --git a/src/core/IronPython.Modules/IronPython.Modules.csproj b/src/core/IronPython.Modules/IronPython.Modules.csproj
index 1f6f3c1a8..ca88b2b9f 100644
--- a/src/core/IronPython.Modules/IronPython.Modules.csproj
+++ b/src/core/IronPython.Modules/IronPython.Modules.csproj
@@ -1,7 +1,7 @@
-
+
- net462;netstandard2.0;net6.0;net8.0
+ net462;netstandard2.0;net6.0;net8.0;net10.0
885063680
true
true
diff --git a/src/core/IronPython.Modules/_ssl.cs b/src/core/IronPython.Modules/_ssl.cs
index 08ade85f6..8887134dd 100644
--- a/src/core/IronPython.Modules/_ssl.cs
+++ b/src/core/IronPython.Modules/_ssl.cs
@@ -252,7 +252,9 @@ public void load_verify_locations(CodeContext context, object cafile = null, str
using IPythonBuffer buf = cabuf.GetBuffer();
var contents = buf.AsReadOnlySpan();
while (contents.Length > 0) {
-#if NET
+#if NET10_0_OR_GREATER
+ var cert = X509CertificateLoader.LoadCertificate(contents);
+#elif NET
var cert = new X509Certificate2(contents);
#else
var cert = new X509Certificate2(contents.ToArray());
@@ -449,7 +451,12 @@ public void do_handshake() {
if (_serverSide) {
var _cert = context._cert;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
- _cert = new X509Certificate2(_cert.Export(X509ContentType.Pkcs12));
+ byte[] certData = _cert.Export(X509ContentType.Pkcs12);
+#if NET10_0_OR_GREATER
+ _cert = X509CertificateLoader.LoadCertificate(certData);
+#else
+ _cert = new X509Certificate2(certData);
+#endif
}
_sslStream.AuthenticateAsServer(_cert, _certsMode == PythonSsl.CERT_REQUIRED, enabledSslProtocols, false);
} else {
@@ -527,6 +534,8 @@ private static SslProtocols GetProtocolType(int protocol, int options) {
#pragma warning restore CS0618 // Type or member is obsolete
#pragma warning restore CA5397 // Do not use deprecated SslProtocols values
+#pragma warning disable SYSLIB0058 // Certain SslStream properties are obsolete
+
public PythonTuple cipher() {
if (_sslStream != null && _sslStream.IsAuthenticated) {
return PythonTuple.MakeTuple(
@@ -540,6 +549,8 @@ public PythonTuple cipher() {
public object compression() => null; // TODO
+#pragma warning restore SYSLIB0058 // Certain SslStream properties are obsolete
+
#pragma warning disable CA5397 // Do not use deprecated SslProtocols values
#pragma warning disable CS0618 // Type or member is obsolete
#pragma warning disable SYSLIB0039 // Type or member is obsolete
@@ -876,7 +887,14 @@ public static PythonDictionary _test_decode_cert(CodeContext context, string pat
private static PythonDictionary CertificateToPython(CodeContext context, X509Certificate cert) {
if (cert is X509Certificate2 cert2)
return CertificateToPython(context, cert2);
- return CertificateToPython(context, new X509Certificate2(cert.GetRawCertData()));
+
+ byte[] certData = cert.GetRawCertData();
+#if NET10_0_OR_GREATER
+ cert2 = X509CertificateLoader.LoadCertificate(certData);
+#else
+ cert2 = new X509Certificate2(certData);
+#endif
+ return CertificateToPython(context, cert2);
}
private static PythonDictionary CertificateToPython(CodeContext context, X509Certificate2 cert) {
@@ -1030,7 +1048,12 @@ private static X509Certificate2 ReadCertificate(CodeContext context, string file
var certStr = ReadToEnd(lines, ref i, "-----END CERTIFICATE-----");
try {
- cert = new X509Certificate2(Convert.FromBase64String(certStr.ToString()));
+ byte[] certData = Convert.FromBase64String(certStr.ToString());
+#if NET10_0_OR_GREATER
+ cert = X509CertificateLoader.LoadCertificate(certData);
+#else
+ cert = new X509Certificate2(certData);
+#endif
} catch (Exception e) {
throw ErrorDecoding(context, filename, e);
}
diff --git a/src/core/IronPython.Modules/fcntl.cs b/src/core/IronPython.Modules/fcntl.cs
index ed9189858..2380d13dd 100644
--- a/src/core/IronPython.Modules/fcntl.cs
+++ b/src/core/IronPython.Modules/fcntl.cs
@@ -117,11 +117,11 @@ public static object fcntl(CodeContext context, object? fd, int cmd, [Optional]
//
// int ioctl(int, unsigned long, ...)
//
- // but .NET, as of Jan 2025, still does not support varargs in P/Invoke [1]
+ // but .NET, as of Jan 2026, still does not support varargs in P/Invoke [1]
// so as a workaround, nonvararg prototypes are defined for each architecture.
// [1]: https://github.com/dotnet/runtime/issues/48796
-#if NET10_0_OR_GREATER
+#if NET11_0_OR_GREATER
#error Check if this version of .NET supports P/Invoke of variadic functions; if not, change the condition to recheck at next major .NET version
#endif
diff --git a/src/core/IronPython/IronPython.csproj b/src/core/IronPython/IronPython.csproj
index 8f0689fa8..576fdc725 100644
--- a/src/core/IronPython/IronPython.csproj
+++ b/src/core/IronPython/IronPython.csproj
@@ -1,7 +1,7 @@
-
+
- net462;netstandard2.0;net6.0;net8.0
+ net462;netstandard2.0;net6.0;net8.0;net10.0
879755264
true
true
@@ -30,7 +30,7 @@
-
+
diff --git a/src/core/IronPython/Runtime/Importer.cs b/src/core/IronPython/Runtime/Importer.cs
index 2cbfa997b..6f3db9812 100644
--- a/src/core/IronPython/Runtime/Importer.cs
+++ b/src/core/IronPython/Runtime/Importer.cs
@@ -769,9 +769,9 @@ private static bool IsReflected(object module) {
private static string CreateFullName(string/*!*/ baseName, ArraySegment parts) {
if (baseName == null || baseName.Length == 0 || baseName == "__main__") {
- return string.Join(".", parts);
+ return string.Join(".", (IEnumerable)parts);
}
- return baseName + "." + string.Join(".", parts);
+ return baseName + "." + string.Join(".", (IEnumerable)parts);
}
#endregion
diff --git a/src/executables/IronPython.Console/IronPython.Console.csproj b/src/executables/IronPython.Console/IronPython.Console.csproj
index 3c75121b2..15afa70ae 100644
--- a/src/executables/IronPython.Console/IronPython.Console.csproj
+++ b/src/executables/IronPython.Console/IronPython.Console.csproj
@@ -1,7 +1,7 @@
-
+
- net462;net6.0;net8.0
+ net462;net6.0;net8.0;net10.0
Exe
IronPython.Console
ipy
diff --git a/src/executables/IronPython.Console32/IronPython.Console32.csproj b/src/executables/IronPython.Console32/IronPython.Console32.csproj
index c8b938c10..cf041671b 100644
--- a/src/executables/IronPython.Console32/IronPython.Console32.csproj
+++ b/src/executables/IronPython.Console32/IronPython.Console32.csproj
@@ -1,7 +1,7 @@
-
+
- net462
+ net462;net6.0;net8.0;net10.0
x86
Exe
IronPython.Console32
diff --git a/src/extensions/IronPython.SQLite/IronPython.SQLite.csproj b/src/extensions/IronPython.SQLite/IronPython.SQLite.csproj
index 8354aee5c..5e6209d8b 100644
--- a/src/extensions/IronPython.SQLite/IronPython.SQLite.csproj
+++ b/src/extensions/IronPython.SQLite/IronPython.SQLite.csproj
@@ -1,7 +1,7 @@
-
+
- net462;netstandard2.0;net6.0;net8.0
+ net462;netstandard2.0;net6.0;net8.0;net10.0
true
SQLITE_DEBUG;TRUE;WIN32;_MSC_VER;SQLITE_ASCII;SQLITE_MEM_POOL;SQLITE_ENABLE_COLUMN_METADATA;SQLITE_OS_WIN;SQLITE_SYSTEM_MALLOC;VDBE_PROFILE_OFF
SQLITE_OMIT_AUTHORIZATION;SQLITE_OMIT_DEPRECATED;SQLITE_OMIT_GET_TABLE;SQLITE_OMIT_INCRBLOB;SQLITE_OMIT_LOOKASIDE;SQLITE_OMIT_SHARED_CACHE;SQLITE_OMIT_UTF16;SQLITE_OMIT_WAL
diff --git a/src/extensions/IronPython.Wpf/IronPython.Wpf.csproj b/src/extensions/IronPython.Wpf/IronPython.Wpf.csproj
index 53618a818..0b810f59f 100644
--- a/src/extensions/IronPython.Wpf/IronPython.Wpf.csproj
+++ b/src/extensions/IronPython.Wpf/IronPython.Wpf.csproj
@@ -1,7 +1,7 @@
-
+
- net462;net6.0-windows;net8.0-windows
+ net462;net6.0-windows;net8.0-windows;net10.0-windows
true
true
true
diff --git a/tests/IronPython.Tests/AttrInjectorTest.cs b/tests/IronPython.Tests/AttrInjectorTest.cs
index 421e9a7f1..7ab969f02 100644
--- a/tests/IronPython.Tests/AttrInjectorTest.cs
+++ b/tests/IronPython.Tests/AttrInjectorTest.cs
@@ -49,7 +49,6 @@ public static object GetBoundMember(object obj, string name) {
} else {
return n;
}
-
}
}
}
@@ -59,4 +58,4 @@ public static object GetBoundMember(object obj, string name) {
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/IronPython.Tests/IronPython.Tests.csproj b/tests/IronPython.Tests/IronPython.Tests.csproj
index 6ff811e82..f9dca9eaa 100644
--- a/tests/IronPython.Tests/IronPython.Tests.csproj
+++ b/tests/IronPython.Tests/IronPython.Tests.csproj
@@ -1,7 +1,7 @@
-
+
- net462;net6.0;net8.0
+ net462;net6.0;net8.0;net10.0
IronPythonTest
true
diff --git a/tests/suite/interop/net/type/test_reachtype.py b/tests/suite/interop/net/type/test_reachtype.py
index 7abedc02b..6e020c870 100644
--- a/tests/suite/interop/net/type/test_reachtype.py
+++ b/tests/suite/interop/net/type/test_reachtype.py
@@ -95,7 +95,7 @@ def test_generic_types(self):
self.assertEqual(G2[int, int].A, 40)
self.assertRaisesRegex(ValueError,
- re.compile(r"(?s)The number of generic arguments provided doesn't equal the arity of the generic type definition\..*Parameter.*instantiation", re.M),
+ re.compile(r"(?s)The number of generic arguments provided doesn't equal the arity of the generic type definition\..*Parameter.*", re.M),
lambda: G3[()])
if is_mono: