diff --git a/.editorconfig b/.editorconfig index d9c7ff3d7..c0c0e76d1 100644 --- a/.editorconfig +++ b/.editorconfig @@ -95,3 +95,6 @@ dotnet_diagnostic.CA5350.severity = suggestion # CA5350: Do Not Use Weak Crypto dotnet_diagnostic.CA5351.severity = suggestion # CA5351: Do Not Use Broken Cryptographic Algorithms dotnet_diagnostic.CA5359.severity = suggestion # CA5359: Do Not Disable Certificate Validation dotnet_diagnostic.CA5372.severity = suggestion # CA5372: Use XmlReader For XPathDocument + +dotnet_diagnostic.SYSLIB1045.severity = suggestion # SYSLIB1045: Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time +dotnet_diagnostic.SYSLIB1054.severity = suggestion # SYSLIB1054: Use 'LibraryImportAttribute' instead of 'DllImportAttribute' to generate P/Invoke marshalling code at compile time diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0ddab2b28..4d96545fa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -27,6 +27,10 @@ jobs: uses: actions/setup-dotnet@v1 with: dotnet-version: '6.0.x' + - name: Setup .NET 7.0 + uses: actions/setup-dotnet@v1 + with: + dotnet-version: '7.0.x' - name: Version Information run: | dotnet --info @@ -50,3 +54,6 @@ jobs: - name: Test (net6.0) run: ./make.ps1 -frameworks net6.0 test-all shell: pwsh + - name: Test (net7.0) + run: ./make.ps1 -frameworks net7.0 test-all + shell: pwsh diff --git a/Build/net7.0-windows.props b/Build/net7.0-windows.props new file mode 100644 index 000000000..4f718b944 --- /dev/null +++ b/Build/net7.0-windows.props @@ -0,0 +1,9 @@ + + + false + $(BaseIntermediateOutputPath)$(Configuration)\net7.0 + $(BaseOutputPath)\net7.0 + + + + diff --git a/Build/net7.0.props b/Build/net7.0.props new file mode 100644 index 000000000..b8e5aa251 --- /dev/null +++ b/Build/net7.0.props @@ -0,0 +1,41 @@ + + + + false + + + + $(Features);FEATURE_APARTMENTSTATE + $(Features);FEATURE_ASSEMBLY_GETFORWARDEDTYPES + $(Features);FEATURE_ASSEMBLY_RESOLVE + $(Features);FEATURE_ASSEMBLYBUILDER_DEFINEDYNAMICASSEMBLY + $(Features);FEATURE_BASIC_CONSOLE + $(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_CONSOLE + $(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_SERIALIZATION + $(Features);FEATURE_STACK_TRACE + $(Features);FEATURE_SYNC_SOCKETS + $(Features);FEATURE_THREAD + $(Features);FEATURE_XMLDOC + + diff --git a/Build/steps.yml b/Build/steps.yml index d4734f405..c76c17f73 100644 --- a/Build/steps.yml +++ b/Build/steps.yml @@ -31,11 +31,17 @@ steps: version: '3.1.x' - task: UseDotNet@2 - displayName: Install .NET 6.0 SDK for build + displayName: Install .NET 6.0 runtime for testing inputs: - packageType: 'sdk' + packageType: 'runtime' version: '6.0.x' + - task: UseDotNet@2 + displayName: Install .NET 7.0 SDK for build + inputs: + packageType: 'sdk' + version: '7.0.x' + # Set Mono version on macOS - ${{ if eq(parameters.os, 'macOS') }}: - task: Bash@3 diff --git a/IronPython.sln b/IronPython.sln index d02363401..0c9caac0f 100644 --- a/IronPython.sln +++ b/IronPython.sln @@ -37,6 +37,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{17737ACB Build\net462.props = Build\net462.props Build\net6.0-windows.props = Build\net6.0-windows.props Build\net6.0.props = Build\net6.0.props + Build\net7.0-windows.props = Build\net7.0-windows.props + Build\net7.0.props = Build\net7.0.props + Build\netcoreapp3.1.props = Build\netcoreapp3.1.props Build\netstandard2.0.props = Build\netstandard2.0.props Build\steps.yml = Build\steps.yml Build\Tasks.Targets = Build\Tasks.Targets diff --git a/Src/IronPython.Modules/IronPython.Modules.csproj b/Src/IronPython.Modules/IronPython.Modules.csproj index 5a7b3cba0..59706a928 100644 --- a/Src/IronPython.Modules/IronPython.Modules.csproj +++ b/Src/IronPython.Modules/IronPython.Modules.csproj @@ -1,7 +1,7 @@  - net462;netstandard2.0;net6.0 + net462;netstandard2.0;net6.0;net7.0 885063680 true true diff --git a/Src/IronPython.Modules/_overlapped.cs b/Src/IronPython.Modules/_overlapped.cs index 0a39d7072..b0f468af7 100644 --- a/Src/IronPython.Modules/_overlapped.cs +++ b/Src/IronPython.Modules/_overlapped.cs @@ -22,7 +22,7 @@ public static class PythonOverlapped { private static extern IntPtr _CreateIoCompletionPort(IntPtr FileHandle, IntPtr ExistingCompletionPort, UIntPtr CompletionKey, uint NumberOfConcurrentThreads); public static BigInteger CreateIoCompletionPort(BigInteger handle, BigInteger port, BigInteger key, int concurrency) { - var res = _CreateIoCompletionPort((IntPtr)(long)handle, (IntPtr)(long)port, (UIntPtr)(ulong)key, (uint)concurrency); + var res = _CreateIoCompletionPort(checked((IntPtr)(long)handle), checked((IntPtr)(long)port), checked((UIntPtr)(ulong)key), (uint)concurrency); if (res == IntPtr.Zero) { throw PythonNT.GetLastWin32Error(); } diff --git a/Src/IronPython.Modules/_socket.cs b/Src/IronPython.Modules/_socket.cs index 51f9f6a36..9a8709e85 100644 --- a/Src/IronPython.Modules/_socket.cs +++ b/Src/IronPython.Modules/_socket.cs @@ -862,7 +862,7 @@ public int sendto([NotNone] IBufferProtocol data, [NotNone] PythonTuple address) /// internal static Socket? HandleToSocket(Int64 handle) { lock (_handleToSocket) { - if (_handleToSocket.TryGetValue((IntPtr)handle, out WeakReference? weakref)) { + if (_handleToSocket.TryGetValue(checked((IntPtr)handle), out WeakReference? weakref)) { return weakref.Target as Socket; } } diff --git a/Src/IronPython.Modules/_winapi.cs b/Src/IronPython.Modules/_winapi.cs index 8a21f05dc..dcfacd5d4 100644 --- a/Src/IronPython.Modules/_winapi.cs +++ b/Src/IronPython.Modules/_winapi.cs @@ -26,7 +26,7 @@ public static class PythonWinApi { throw new NotImplementedException(); } else { - var result = ConnectNamedPipe((IntPtr)(long)handle, IntPtr.Zero); + var result = ConnectNamedPipe(checked((IntPtr)(long)handle), IntPtr.Zero); if (!result) throw PythonNT.GetLastWin32Error(); diff --git a/Src/IronPython.SQLite/IronPython.SQLite.csproj b/Src/IronPython.SQLite/IronPython.SQLite.csproj index f00505312..f86bded8f 100644 --- a/Src/IronPython.SQLite/IronPython.SQLite.csproj +++ b/Src/IronPython.SQLite/IronPython.SQLite.csproj @@ -1,7 +1,7 @@  - net462;netstandard2.0;net6.0 + net462;netstandard2.0;net6.0;net7.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/IronPython.Wpf/IronPython.Wpf.csproj b/Src/IronPython.Wpf/IronPython.Wpf.csproj index 9d0ff5997..d9f0de2c8 100644 --- a/Src/IronPython.Wpf/IronPython.Wpf.csproj +++ b/Src/IronPython.Wpf/IronPython.Wpf.csproj @@ -1,7 +1,7 @@  - net462;net6.0-windows + net462;net6.0-windows;net7.0-windows true true true diff --git a/Src/IronPython/IronPython.csproj b/Src/IronPython/IronPython.csproj index 65dcb580f..a3daf978b 100644 --- a/Src/IronPython/IronPython.csproj +++ b/Src/IronPython/IronPython.csproj @@ -1,7 +1,7 @@  - net462;netstandard2.0;net6.0 + net462;netstandard2.0;net6.0;net7.0 879755264 true true diff --git a/Src/IronPython/Runtime/Operations/PythonOps.cs b/Src/IronPython/Runtime/Operations/PythonOps.cs index cd2d757b2..689e9ebf2 100644 --- a/Src/IronPython/Runtime/Operations/PythonOps.cs +++ b/Src/IronPython/Runtime/Operations/PythonOps.cs @@ -4024,7 +4024,7 @@ internal static void PrintWithDestNoNewline(CodeContext/*!*/ context, object des } public static Exception InvalidType(object o, RuntimeTypeHandle handle) { - return PythonOps.TypeErrorForTypeMismatch(DynamicHelpers.GetPythonTypeFromType(Type.GetTypeFromHandle(handle)).Name, o); + return PythonOps.TypeErrorForTypeMismatch(DynamicHelpers.GetPythonTypeFromType(Type.GetTypeFromHandle(handle)!).Name, o); } public static Exception ZeroDivisionError() { diff --git a/Src/IronPythonConsole/IronPythonConsole.csproj b/Src/IronPythonConsole/IronPythonConsole.csproj index 73024a0c8..8dc8f7bc2 100644 --- a/Src/IronPythonConsole/IronPythonConsole.csproj +++ b/Src/IronPythonConsole/IronPythonConsole.csproj @@ -1,7 +1,7 @@  - net462;netcoreapp3.1;net6.0 + net462;netcoreapp3.1;net6.0;net7.0 false Exe diff --git a/Src/IronPythonTest/Cases/IronPythonCasesManifest.ini b/Src/IronPythonTest/Cases/IronPythonCasesManifest.ini index 214561311..b9ddeec81 100644 --- a/Src/IronPythonTest/Cases/IronPythonCasesManifest.ini +++ b/Src/IronPythonTest/Cases/IronPythonCasesManifest.ini @@ -86,6 +86,9 @@ Reason=Needs to be redone as two tests Ignore=true Reason=StackOverflowException - https://github.com/IronLanguages/ironpython2/issues/182 +[IronPython.test_re_stdlib] +IsolationLevel=PROCESS # workaround for StackOverflowException on macOS on .NET 7 + [IronPython.test_regressions] IsolationLevel=PROCESS # https://github.com/IronLanguages/ironpython3/issues/489 RetryCount=2 diff --git a/Src/IronPythonTest/IronPythonTest.csproj b/Src/IronPythonTest/IronPythonTest.csproj index 118756389..ed1fe9d3a 100644 --- a/Src/IronPythonTest/IronPythonTest.csproj +++ b/Src/IronPythonTest/IronPythonTest.csproj @@ -1,7 +1,7 @@  - net462;netcoreapp3.1;net6.0 + net462;netcoreapp3.1;net6.0;net7.0 false true diff --git a/Tests/test_cliclass.py b/Tests/test_cliclass.py index 771628c52..ee037177f 100644 --- a/Tests/test_cliclass.py +++ b/Tests/test_cliclass.py @@ -4,7 +4,7 @@ import sys import unittest -from iptest import IronPythonTestCase, is_cli, is_debug, is_mono, is_netcoreapp, is_netcoreapp21, is_posix, big, run_test, skipUnlessIronPython +from iptest import IronPythonTestCase, is_cli, is_debug, is_mono, is_net70, is_netcoreapp, is_netcoreapp21, is_posix, big, run_test, skipUnlessIronPython if is_cli: import clr @@ -1421,6 +1421,7 @@ def test_clr_dir(self): self.assertTrue('IndexOf' not in clr.Dir('abc')) self.assertTrue('IndexOf' in clr.DirClr('abc')) + @unittest.skipIf(is_net70, "TODO") # TODO: https://github.com/IronLanguages/ironpython3/issues/1485 def test_int32_bigint_equivalence(self): import math diff --git a/Tests/test_int.py b/Tests/test_int.py index 8fcbe5404..34ab61d16 100644 --- a/Tests/test_int.py +++ b/Tests/test_int.py @@ -4,7 +4,7 @@ import sys -from iptest import IronPythonTestCase, is_cli, is_netstandard, is_mono, big, myint, skipUnlessIronPython, run_test +from iptest import IronPythonTestCase, is_cli, is_net70, is_netstandard, is_mono, big, myint, skipUnlessIronPython, run_test class IntNoClrTest(IronPythonTestCase): """Must be run before IntTest because it depends on CLR API not being visible.""" @@ -27,14 +27,19 @@ def test_instance_set(self): self.assertSetEqual(set(dir(j)) - set(dir(i)), {'GetByteCount', 'TryWriteBytes'}) self.assertSetEqual(set(dir(int)) - set(dir(Int32)), {'GetByteCount', 'TryWriteBytes'}) - # these two assertions fail on IronPython compiled for .NET Standard - if not is_netstandard: - self.assertSetEqual(set(dir(i)) - set(dir(j)), {'MaxValue', 'MinValue'}) - self.assertSetEqual(set(dir(Int32)) - set(dir(int)), {'MaxValue', 'MinValue'}) - - # weaker assertions that should always hold - self.assertTrue((set(dir(i)) - set(dir(j))).issubset({'MaxValue', 'MinValue', 'GetByteCount', 'TryWriteBytes', 'GetBitLength'})) - self.assertTrue((set(dir(Int32)) - set(dir(int))).issubset({'MaxValue', 'MinValue', 'GetByteCount', 'TryWriteBytes', 'GetBitLength'})) + if is_net70: # https://github.com/IronLanguages/ironpython3/issues/1485 + diff = {'TryConvertToChecked', 'MinValue', 'TryConvertFromChecked', 'MaxValue', 'TryConvertFromTruncating', 'WriteBigEndian', 'GetShortestBitLength', 'TryWriteLittleEndian', 'WriteLittleEndian', 'TryConvertToSaturating', 'TryConvertFromSaturating', 'TryWriteBigEndian', 'TryConvertToTruncating'} + self.assertSetEqual(set(dir(i)) - set(dir(j)), diff) + self.assertSetEqual(set(dir(Int32)) - set(dir(int)), diff) + else: + # these two assertions fail on IronPython compiled for .NET Standard + if not is_netstandard: + self.assertSetEqual(set(dir(i)) - set(dir(j)), {'MaxValue', 'MinValue'}) + self.assertSetEqual(set(dir(Int32)) - set(dir(int)), {'MaxValue', 'MinValue'}) + + # weaker assertions that should always hold + self.assertTrue((set(dir(i)) - set(dir(j))).issubset({'MaxValue', 'MinValue', 'GetByteCount', 'TryWriteBytes', 'GetBitLength'})) + self.assertTrue((set(dir(Int32)) - set(dir(int))).issubset({'MaxValue', 'MinValue', 'GetByteCount', 'TryWriteBytes', 'GetBitLength'})) def test_from_bytes(self): self.assertEqual(type(int.from_bytes(b"abc", "big")), int) diff --git a/Tests/test_methodbinder1.py b/Tests/test_methodbinder1.py index 800be2f68..d5b2e41a6 100644 --- a/Tests/test_methodbinder1.py +++ b/Tests/test_methodbinder1.py @@ -8,7 +8,7 @@ import unittest -from iptest import IronPythonTestCase, is_cli, is_mono, is_netcoreapp, run_test, skipUnlessIronPython +from iptest import IronPythonTestCase, is_mono, is_net70, is_netcoreapp, run_test, skipUnlessIronPython from iptest.type_util import * from System import Int32 @@ -102,7 +102,7 @@ def test_this_matrix(self): funcnames = "M201 M680 M202 M203 M681 M204 M205 M301 M302 M303 M304 M310 M311 M312 M313 M320 M321 M400".split() - matrix = ( + matrix = [ #### M201 M680 M202 M203 M681 M204 M205 M301 M302 M303 M304 M310 M311 M312 M313 M320 M321 M400 #### int int? double bigint bigint? bool str sbyte i16 i64 single byte ui16 ui32 ui64 char decm obj ( "SByteMax", True, True, True, True, True, True, TypeE, True, True, True, True, True, True, True, True, TypeE, True, True, ), @@ -172,16 +172,17 @@ def test_this_matrix(self): ( (3+0j), TypeE, TypeE, TypeE, TypeE, TypeE, True, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, True, ), ( (3+1j), TypeE, TypeE, TypeE, TypeE, TypeE, True, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, True, ), ( mycomplex1, TypeE, TypeE, TypeE, TypeE, TypeE, True, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, True, ) - ) + ] - InvariantCulture = System.Globalization.CultureInfo.InvariantCulture - matrix = list(matrix) + + ch2bi = True if is_net70 else TypeE # .NET 7 adds an implicit cast from Char to BigInteger ################################################## pass in char ######################################################### #### M201 M680 M202 M203 M681 M204 M205 M301 M302 M303 M304 M310 M311 M312 M313 M320 M321 M400 #### int int? double bigint bigint? bool str sbyte i16 i64 single byte ui16 ui32 ui64 char decm obj - matrix.append((System.Char.Parse('A'), TypeE, TypeE, TypeE, TypeE, TypeE, True, True, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, True, True, True, )) + matrix.append((System.Char.Parse('A'), TypeE, TypeE, TypeE, ch2bi, ch2bi, True, True, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, TypeE, True, True, True, )) + InvariantCulture = System.Globalization.CultureInfo.InvariantCulture ################################################## pass in float ######################################################### #### single/double becomes Int32/BigInteger, but this does not apply to other primitive types #### M201 M680 M202 M203 M681 M204 M205 M301 M302 M303 M304 M310 M311 M312 M313 M320 M321 M400 @@ -190,7 +191,6 @@ def test_this_matrix(self): matrix.append((System.Double.Parse("10.2", InvariantCulture), TypeE, TypeE, True, TypeE, TypeE, True, TypeE, TypeE, TypeE, TypeE, True, TypeE, TypeE, TypeE, TypeE, TypeE, True, True, )) matrix.append((System.Single.Parse("-8.1", InvariantCulture), TypeE, TypeE, True, TypeE, TypeE, True, TypeE, TypeE, TypeE, TypeE, True, TypeE, TypeE, TypeE, TypeE, TypeE, True, True, )) matrix.append((System.Double.Parse("-1.8", InvariantCulture), TypeE, TypeE, True, TypeE, TypeE, True, TypeE, TypeE, TypeE, TypeE, True, TypeE, TypeE, TypeE, TypeE, TypeE, True, True, )) - matrix = tuple(matrix) for scenario in matrix: if isinstance(scenario[0], str): diff --git a/make.ps1 b/make.ps1 index f14921289..6e2472979 100755 --- a/make.ps1 +++ b/make.ps1 @@ -4,7 +4,7 @@ Param( [Parameter(Position=1)] [String] $target = "build", [String] $configuration = "Release", - [String[]] $frameworks=@('net462','netcoreapp3.1','net6.0'), + [String[]] $frameworks=@('net462','netcoreapp3.1','net6.0','net7.0'), [String] $platform = "x64", [switch] $runIgnored, [int] $jobs = [System.Environment]::ProcessorCount