diff --git a/.editorconfig b/.editorconfig index c0c0e76d1..f7658ff73 100644 --- a/.editorconfig +++ b/.editorconfig @@ -60,6 +60,9 @@ dotnet_diagnostic.CA1305.severity = none # CA1305: Specify IFormatProvide dotnet_diagnostic.CA1307.severity = suggestion # CA1307: Specify StringComparison for clarity dotnet_diagnostic.CA1309.severity = suggestion # CA1309: Use ordinal string comparison dotnet_diagnostic.CA1310.severity = warning # CA1310: Specify StringComparison for correctness +dotnet_diagnostic.CA1510.severity = none # CA1510: Use ArgumentNullException throw helper +dotnet_diagnostic.CA1512.severity = none # CA1512: Use ArgumentOutOfRangeException throw helper +dotnet_diagnostic.CA1513.severity = none # CA1513: Use ObjectDisposedException throw helper dotnet_diagnostic.CA1707.severity = none # CA1707: Identifiers should not contain underscores dotnet_diagnostic.CA1708.severity = none # CA1708: Identifiers should differ by more than case dotnet_diagnostic.CA1710.severity = none # CA1710: Identifiers should have correct suffix @@ -81,8 +84,10 @@ dotnet_diagnostic.CA1845.severity = none # CA1845: Use span-based 'string dotnet_diagnostic.CA1846.severity = none # CA1846: Prefer 'AsSpan' over 'Substring' dotnet_diagnostic.CA1847.severity = none # CA1847: Use char literal for a single character lookup dotnet_diagnostic.CA1852.severity = suggestion # CA1852: Seal internal types +dotnet_diagnostic.CA1854.severity = suggestion # CA1854: Prefer the 'IDictionary.TryGetValue(TKey, out TValue)' method dotnet_diagnostic.CA1859.severity = suggestion # CA1859: Use concrete types when possible for improved performance dotnet_diagnostic.CA1861.severity = suggestion # CA1861: Avoid constant arrays as arguments +dotnet_diagnostic.CA1863.severity = none # CA1863: Use 'CompositeFormat' dotnet_diagnostic.CA2101.severity = suggestion # CA2101: Specify marshaling for P/Invoke string arguments dotnet_diagnostic.CA2201.severity = none # CA2201: Do not raise reserved exception types dotnet_diagnostic.CA2208.severity = suggestion # CA2208: Instantiate argument exceptions correctly diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4d96545fa..cc4b4e0e2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - os: [windows-latest, ubuntu-latest, macos-latest] + os: [windows-latest, ubuntu-latest, macos-latest-large] steps: - name: Install tools @@ -27,10 +27,10 @@ jobs: uses: actions/setup-dotnet@v1 with: dotnet-version: '6.0.x' - - name: Setup .NET 7.0 + - name: Setup .NET 8.0 uses: actions/setup-dotnet@v1 with: - dotnet-version: '7.0.x' + dotnet-version: '8.0.x' - name: Version Information run: | dotnet --info @@ -54,6 +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 + - name: Test (net8.0) + run: ./make.ps1 -frameworks net8.0 test-all shell: pwsh diff --git a/Build/net7.0-windows.props b/Build/net7.0-windows.props deleted file mode 100644 index 4f718b944..000000000 --- a/Build/net7.0-windows.props +++ /dev/null @@ -1,9 +0,0 @@ - - - false - $(BaseIntermediateOutputPath)$(Configuration)\net7.0 - $(BaseOutputPath)\net7.0 - - - - diff --git a/Build/net8.0-windows.props b/Build/net8.0-windows.props new file mode 100644 index 000000000..8e9067699 --- /dev/null +++ b/Build/net8.0-windows.props @@ -0,0 +1,9 @@ + + + false + $(BaseIntermediateOutputPath)$(Configuration)\net8.0 + $(BaseOutputPath)\net8.0 + + + + diff --git a/Build/net7.0.props b/Build/net8.0.props similarity index 91% rename from Build/net7.0.props rename to Build/net8.0.props index b8e5aa251..926dadc14 100644 --- a/Build/net7.0.props +++ b/Build/net8.0.props @@ -9,7 +9,6 @@ $(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 @@ -17,7 +16,6 @@ $(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 @@ -32,7 +30,6 @@ $(Features);FEATURE_REGISTRY $(Features);FEATURE_RUNTIMEINFORMATION $(Features);FEATURE_SECURITY_RULES - $(Features);FEATURE_SERIALIZATION $(Features);FEATURE_STACK_TRACE $(Features);FEATURE_SYNC_SOCKETS $(Features);FEATURE_THREAD diff --git a/Build/net9.0-windows.props b/Build/net9.0-windows.props new file mode 100644 index 000000000..b64bb8ce9 --- /dev/null +++ b/Build/net9.0-windows.props @@ -0,0 +1,9 @@ + + + false + $(BaseIntermediateOutputPath)$(Configuration)\net9.0 + $(BaseOutputPath)\net9.0 + + + + diff --git a/Build/net9.0.props b/Build/net9.0.props new file mode 100644 index 000000000..926dadc14 --- /dev/null +++ b/Build/net9.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/Build/steps.yml b/Build/steps.yml index c76c17f73..12a52759c 100644 --- a/Build/steps.yml +++ b/Build/steps.yml @@ -37,10 +37,10 @@ steps: version: '6.0.x' - task: UseDotNet@2 - displayName: Install .NET 7.0 SDK for build + displayName: Install .NET 8.0 SDK for build inputs: packageType: 'sdk' - version: '7.0.x' + version: '8.0.x' # Set Mono version on macOS - ${{ if eq(parameters.os, 'macOS') }}: diff --git a/IronPython.sln b/IronPython.sln index 0c9caac0f..3de1c02d7 100644 --- a/IronPython.sln +++ b/IronPython.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.28917.181 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34714.143 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IronPython", "Src\IronPython\IronPython.csproj", "{95289EA9-5778-489D-AB48-F81F2CE2DA32}" EndProject @@ -37,8 +37,10 @@ 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\net8.0-windows.props = Build\net8.0-windows.props + Build\net8.0.props = Build\net8.0.props + Build\net9.0-windows.props = Build\net9.0-windows.props + Build\net9.0.props = Build\net9.0.props Build\netcoreapp3.1.props = Build\netcoreapp3.1.props Build\netstandard2.0.props = Build\netstandard2.0.props Build\steps.yml = Build\steps.yml diff --git a/IronPythonAnalyzer/IronPythonAnalyzer/IronPythonAnalyzer.csproj b/IronPythonAnalyzer/IronPythonAnalyzer/IronPythonAnalyzer.csproj index 14e1f56a7..38c0895fe 100644 --- a/IronPythonAnalyzer/IronPythonAnalyzer/IronPythonAnalyzer.csproj +++ b/IronPythonAnalyzer/IronPythonAnalyzer/IronPythonAnalyzer.csproj @@ -2,11 +2,12 @@ netstandard2.0 + true - - + + diff --git a/Package/msi/IronPython.Installer.wixproj b/Package/msi/IronPython.Installer.wixproj index b8e471091..e122f51c8 100644 --- a/Package/msi/IronPython.Installer.wixproj +++ b/Package/msi/IronPython.Installer.wixproj @@ -1,4 +1,4 @@ - + x64 3.4 @@ -44,10 +44,10 @@ - - - - + + + + diff --git a/Package/nuget/IronPython.nuspec b/Package/nuget/IronPython.nuspec index 3cc2a5d76..8711f555a 100644 --- a/Package/nuget/IronPython.nuspec +++ b/Package/nuget/IronPython.nuspec @@ -33,12 +33,16 @@ This package contains the IronPython interpreter engine. + + + + - - - + + + diff --git a/Package/zip/Zip.Packaging.targets b/Package/zip/Zip.Packaging.targets index cc1f64bb8..bec14c1fa 100644 --- a/Package/zip/Zip.Packaging.targets +++ b/Package/zip/Zip.Packaging.targets @@ -4,7 +4,7 @@ - + diff --git a/Src/DLR b/Src/DLR index 872730ab3..fe26cf45d 160000 --- a/Src/DLR +++ b/Src/DLR @@ -1 +1 @@ -Subproject commit 872730ab305d37f67179db8ca778d1cd22984e67 +Subproject commit fe26cf45d383be65a56f0d4b964644eff89e01a8 diff --git a/Src/IronPython.Modules/IronPython.Modules.csproj b/Src/IronPython.Modules/IronPython.Modules.csproj index 59706a928..4fc2771d2 100644 --- a/Src/IronPython.Modules/IronPython.Modules.csproj +++ b/Src/IronPython.Modules/IronPython.Modules.csproj @@ -1,7 +1,7 @@  - net462;netstandard2.0;net6.0;net7.0 + net462;netstandard2.0;net6.0;net8.0 885063680 true true diff --git a/Src/IronPython.Modules/_codecs.cs b/Src/IronPython.Modules/_codecs.cs index d12512404..277b74160 100644 --- a/Src/IronPython.Modules/_codecs.cs +++ b/Src/IronPython.Modules/_codecs.cs @@ -606,7 +606,7 @@ private static Tuple DoEncode(CodeContext context, string encodingNa /// /// Optimized encoding mapping that can be consumed by charmap_encode/EncodingMapEncoding. /// - [PythonHidden] + [PythonType, PythonHidden] public class EncodingMap { private readonly string _smap; [DisallowNull] private Dictionary? _dmap; diff --git a/Src/IronPython.Modules/_csv.cs b/Src/IronPython.Modules/_csv.cs index 819b83a16..9623552b7 100644 --- a/Src/IronPython.Modules/_csv.cs +++ b/Src/IronPython.Modules/_csv.cs @@ -643,7 +643,7 @@ public bool MoveNext() { // If we ended on an escaped newline, then we want to continue onto // the nextline without processing the end of this one, as the newline // is in the middle of the field. - if ((line.EndsWith("\n", StringComparison.Ordinal) || line.EndsWith("\r", StringComparison.Ordinal)) && _state == State.InField) { + if ((line.EndsWith('\n') || line.EndsWith('\r')) && _state == State.InField) { continue; } } diff --git a/Src/IronPython.Modules/_ctypes/_ctypes.cs b/Src/IronPython.Modules/_ctypes/_ctypes.cs index a7a6ab354..1ac41dad2 100644 --- a/Src/IronPython.Modules/_ctypes/_ctypes.cs +++ b/Src/IronPython.Modules/_ctypes/_ctypes.cs @@ -546,10 +546,12 @@ private static ModuleBuilder DynamicModule { lock (_nativeTypes) { if (!_nativeTypes.TryGetValue(size, out Type res)) { int sizeRemaining = size; +#pragma warning disable SYSLIB0050 // Type or member is obsolete TypeBuilder tb = DynamicModule.DefineType("interop_type_size_" + size, TypeAttributes.Public | TypeAttributes.SequentialLayout | TypeAttributes.Sealed | TypeAttributes.Serializable, typeof(ValueType), size); +#pragma warning restore SYSLIB0050 // Type or member is obsolete while (sizeRemaining > 8) { tb.DefineField("field" + sizeRemaining, typeof(long), FieldAttributes.Private); diff --git a/Src/IronPython.Modules/_operator.cs b/Src/IronPython.Modules/_operator.cs index 92f262936..7dd04872a 100644 --- a/Src/IronPython.Modules/_operator.cs +++ b/Src/IronPython.Modules/_operator.cs @@ -59,7 +59,7 @@ private static object GetOneAttr(CodeContext context, object param, object val) int dotPos = s.IndexOf('.'); if (dotPos >= 0) { object nextParam = GetOneAttr(context, param, s.Substring(0, dotPos)); - return GetOneAttr(context, nextParam, s.Substring(dotPos + 1, s.Length - dotPos - 1)); + return GetOneAttr(context, nextParam, s.Substring(dotPos + 1)); } return PythonOps.GetBoundAttr(context, param, s); } diff --git a/Src/IronPython.Modules/_socket.cs b/Src/IronPython.Modules/_socket.cs index 9a8709e85..9587d6864 100644 --- a/Src/IronPython.Modules/_socket.cs +++ b/Src/IronPython.Modules/_socket.cs @@ -2215,10 +2215,6 @@ internal struct WSAData { [DllImport("ws2_32.dll", SetLastError = true)] private static extern Int32 WSACleanup(); - private static T PtrToStructure(IntPtr result) { - return (T)Marshal.PtrToStructure(result, typeof(T))!; - } - public static string GetServiceByPort(ushort port, string? protocol) { if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX) return GetServiceByPortNonWindows(port, protocol); @@ -2235,9 +2231,9 @@ static string GetServiceByPortWindows(ushort port, string? protocol) { throw new SocketUtilException(string.Format("Could not resolve service for port {0}", port)); if (Environment.Is64BitProcess) - return PtrToStructure(result).s_name; + return Marshal.PtrToStructure(result).s_name; else - return PtrToStructure(result).s_name; + return Marshal.PtrToStructure(result).s_name; } static string GetServiceByPortNonWindows(ushort port, string? protocol) { @@ -2248,7 +2244,7 @@ static string GetServiceByPortNonWindows(ushort port, string? protocol) { string.Format("Could not resolve service for port {0}", port)); } - return PtrToStructure(result).s_name; + return Marshal.PtrToStructure(result).s_name; } } @@ -2267,9 +2263,9 @@ static ushort GetServiceByNameWindows(string service, string? protocol) { ushort port; if (Environment.Is64BitProcess) - port = PtrToStructure(result).s_port; + port = Marshal.PtrToStructure(result).s_port; else - port = PtrToStructure(result).s_port; + port = Marshal.PtrToStructure(result).s_port; var hostport = IPAddress.NetworkToHostOrder(unchecked((short)port)); return unchecked((ushort)hostport); @@ -2282,7 +2278,7 @@ static ushort GetServiceByNameNonWindows(string service, string? protocol) { string.Format("Could not resolve port for service {0}", service)); } - ushort port = PtrToStructure(result).s_port; + ushort port = Marshal.PtrToStructure(result).s_port; var hostport = IPAddress.NetworkToHostOrder(unchecked((short)port)); return unchecked((ushort)hostport); } diff --git a/Src/IronPython.Modules/array.cs b/Src/IronPython.Modules/array.cs index 275f9cc92..578ec8d2f 100644 --- a/Src/IronPython.Modules/array.cs +++ b/Src/IronPython.Modules/array.cs @@ -252,7 +252,7 @@ public PythonTuple buffer_info() { } public void byteswap() { - Stream s = ToStream(); + MemoryStream s = ToStream(); byte[] bytes = new byte[s.Length]; s.Read(bytes, 0, bytes.Length); @@ -618,7 +618,7 @@ public PythonList tolist() { } public Bytes tobytes() { - Stream s = ToStream(); + MemoryStream s = ToStream(); byte[] bytes = new byte[s.Length]; s.Read(bytes, 0, (int)s.Length); return Bytes.Make(bytes); diff --git a/Src/IronPython.Modules/binascii.cs b/Src/IronPython.Modules/binascii.cs index 9049ab669..ed4e6f7ed 100644 --- a/Src/IronPython.Modules/binascii.cs +++ b/Src/IronPython.Modules/binascii.cs @@ -59,7 +59,7 @@ static Bytes a2b_uu_impl(CodeContext/*!*/ context, ReadOnlySpan data) { } using MemoryStream res = DecodeWorker(context, data, true, UuDecFunc); - if (suffix == null) { + if (suffix.IsEmpty) { var pad = new byte[lenDec - res.Length]; res.Write(pad, 0, pad.Length); } else { diff --git a/Src/IronPython.Modules/grp.cs b/Src/IronPython.Modules/grp.cs index 80f3a4520..d46de20f5 100644 --- a/Src/IronPython.Modules/grp.cs +++ b/Src/IronPython.Modules/grp.cs @@ -75,7 +75,7 @@ internal struct_group(string gr_name, string gr_passwd, int gr_gid, PythonList g } private static struct_group Make(IntPtr pwd) { - group g = (group)Marshal.PtrToStructure(pwd, typeof(group)); + group g = Marshal.PtrToStructure(pwd); return new struct_group(g.gr_name, g.gr_passwd, g.gr_gid, PythonList.FromEnumerable(MarshalStringArray(g.gr_mem))); } diff --git a/Src/IronPython.Modules/pwd.cs b/Src/IronPython.Modules/pwd.cs index 510e47109..1eb3b015b 100644 --- a/Src/IronPython.Modules/pwd.cs +++ b/Src/IronPython.Modules/pwd.cs @@ -106,10 +106,10 @@ internal struct_passwd(string pw_name, string pw_passwd, int pw_uid, int pw_gid, private static struct_passwd Make(IntPtr pwd) { struct_passwd res = null; if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { - passwd_osx p = (passwd_osx)Marshal.PtrToStructure(pwd, typeof(passwd_osx)); + passwd_osx p = Marshal.PtrToStructure(pwd); res = new struct_passwd(p.pw_name, p.pw_passwd, p.pw_uid, p.pw_gid, p.pw_gecos, p.pw_dir, p.pw_shell); } else { - passwd_linux p = (passwd_linux)Marshal.PtrToStructure(pwd, typeof(passwd_linux)); + passwd_linux p = Marshal.PtrToStructure(pwd); res = new struct_passwd(p.pw_name, p.pw_passwd, p.pw_uid, p.pw_gid, p.pw_gecos, p.pw_dir, p.pw_shell); } diff --git a/Src/IronPython.Modules/spwd.cs b/Src/IronPython.Modules/spwd.cs index 695ff6535..9445f7341 100644 --- a/Src/IronPython.Modules/spwd.cs +++ b/Src/IronPython.Modules/spwd.cs @@ -90,7 +90,7 @@ internal struct_spwd(string sp_nam, string sp_pwd, int sp_lstchg, int sp_min, in } private static struct_spwd Make(IntPtr pwd) { - spwd p = (spwd)Marshal.PtrToStructure(pwd, typeof(spwd)); + spwd p = Marshal.PtrToStructure(pwd); return new struct_spwd(p.sp_namp, p.sp_pwdp, p.sp_lstchg, p.sp_min, p.sp_max, p.sp_warn, p.sp_inact, p.sp_expire, p.sp_flag); } diff --git a/Src/IronPython.SQLite/IronPython.SQLite.csproj b/Src/IronPython.SQLite/IronPython.SQLite.csproj index f86bded8f..60466e71a 100644 --- a/Src/IronPython.SQLite/IronPython.SQLite.csproj +++ b/Src/IronPython.SQLite/IronPython.SQLite.csproj @@ -1,7 +1,7 @@  - net462;netstandard2.0;net6.0;net7.0 + net462;netstandard2.0;net6.0;net8.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.SQLite/c#sqlite/ctime_c.cs b/Src/IronPython.SQLite/c#sqlite/ctime_c.cs index ad8dfbf01..5f7917a0e 100644 --- a/Src/IronPython.SQLite/c#sqlite/ctime_c.cs +++ b/Src/IronPython.SQLite/c#sqlite/ctime_c.cs @@ -1,3 +1,5 @@ +#pragma warning disable CA1865 // Use char overload + namespace Community.CsharpSqlite { using sqlite3_value = Sqlite3.Mem; diff --git a/Src/IronPython.SQLite/c#sqlite/tokenize_c.cs b/Src/IronPython.SQLite/c#sqlite/tokenize_c.cs index a326c7959..71b7f5aa4 100644 --- a/Src/IronPython.SQLite/c#sqlite/tokenize_c.cs +++ b/Src/IronPython.SQLite/c#sqlite/tokenize_c.cs @@ -627,7 +627,7 @@ static int sqlite3RunParser( Parse pParse, string zSql, ref string pzErrMsg ) } } abort_parse: - pParse.zTail = new StringBuilder( zSql.Length <= i ? "" : zSql.Substring( i, zSql.Length - i ) ); + pParse.zTail = new StringBuilder( zSql.Length <= i ? "" : zSql.Substring( i ) ); if ( zSql.Length >= i && nErr == 0 && pParse.rc == SQLITE_OK ) { if ( lastTokenParsed != TK_SEMI ) diff --git a/Src/IronPython.Wpf/IronPython.Wpf.csproj b/Src/IronPython.Wpf/IronPython.Wpf.csproj index d9f0de2c8..97f2aebb6 100644 --- a/Src/IronPython.Wpf/IronPython.Wpf.csproj +++ b/Src/IronPython.Wpf/IronPython.Wpf.csproj @@ -1,7 +1,7 @@  - net462;net6.0-windows;net7.0-windows + net462;net6.0-windows;net8.0-windows true true true diff --git a/Src/IronPython/Compiler/Ast/FunctionDefinition.cs b/Src/IronPython/Compiler/Ast/FunctionDefinition.cs index 270725fad..edc452a27 100644 --- a/Src/IronPython/Compiler/Ast/FunctionDefinition.cs +++ b/Src/IronPython/Compiler/Ast/FunctionDefinition.cs @@ -696,6 +696,7 @@ private LightLambdaExpression CreateFunctionLambda() { // wrap a scope if needed bodyStmt = Ast.Block(locals.ToReadOnlyCollection(), bodyStmt); +#pragma warning disable CA2263 // Prefer generic overload when type is known return AstUtils.LightLambda( typeof(object), delegateType, @@ -703,6 +704,7 @@ private LightLambdaExpression CreateFunctionLambda() { Name + "$" + Interlocked.Increment(ref _lambdaId), parameters ); +#pragma warning restore CA2263 // Prefer generic overload when type is known } internal override LightLambdaExpression GetLambda() => EnsureFunctionLambda(); diff --git a/Src/IronPython/Compiler/Parser.cs b/Src/IronPython/Compiler/Parser.cs index 79814cb28..ddbf3b02e 100644 --- a/Src/IronPython/Compiler/Parser.cs +++ b/Src/IronPython/Compiler/Parser.cs @@ -274,7 +274,7 @@ public static int GetNextAutoIndentSize(string text, int autoIndentTabWidth) { int autoIndentSize = startingSpaces; // Increase the indent if this looks like the start of a compounds statement. // Ideally, we would ask the parser to tell us the exact indentation level - if (lastLine.TrimEnd(whiteSpace).EndsWith(":", StringComparison.Ordinal)) + if (lastLine.TrimEnd(whiteSpace).EndsWith(':')) autoIndentSize += autoIndentTabWidth; return autoIndentSize; diff --git a/Src/IronPython/Hosting/PythonCommandLine.cs b/Src/IronPython/Hosting/PythonCommandLine.cs index 3d1a9fee6..afc65ea3c 100644 --- a/Src/IronPython/Hosting/PythonCommandLine.cs +++ b/Src/IronPython/Hosting/PythonCommandLine.cs @@ -288,7 +288,7 @@ private void InitializeModules() { for (var i = 0; i < 2; i++) { if (File.Exists(path)) { foreach (var line in File.ReadAllLines(path, Encoding.UTF8)) { // TODO: this actually needs to be decoded with surrogateescape - if (line.StartsWith("#", StringComparison.Ordinal)) continue; + if (line.StartsWith('#')) continue; var split = line.Split(new[] { '=' }, 2); if (split.Length != 2) continue; if (split[0].Trim() == "home") { diff --git a/Src/IronPython/Hosting/PythonOptionsParser.cs b/Src/IronPython/Hosting/PythonOptionsParser.cs index 47de95239..1bd42ee80 100644 --- a/Src/IronPython/Hosting/PythonOptionsParser.cs +++ b/Src/IronPython/Hosting/PythonOptionsParser.cs @@ -157,7 +157,7 @@ protected override void ParseArgument(string/*!*/ arg) { return; } - if (arg.StartsWith("-", StringComparison.Ordinal)) { + if (arg.StartsWith('-')) { if (arg.StartsWith("-X:", StringComparison.Ordinal)) { // old implementation specific options for compat switch (arg) { diff --git a/Src/IronPython/IronPython.csproj b/Src/IronPython/IronPython.csproj index a3daf978b..41e1bb9eb 100644 --- a/Src/IronPython/IronPython.csproj +++ b/Src/IronPython/IronPython.csproj @@ -1,7 +1,7 @@  - net462;netstandard2.0;net6.0;net7.0 + net462;netstandard2.0;net6.0;net8.0 879755264 true true diff --git a/Src/IronPython/Lib/iptest/test_env.py b/Src/IronPython/Lib/iptest/test_env.py index 94006df20..bbcd239b5 100644 --- a/Src/IronPython/Lib/iptest/test_env.py +++ b/Src/IronPython/Lib/iptest/test_env.py @@ -21,6 +21,8 @@ is_netcoreapp31 = False is_net60 = False is_net70 = False +is_net80 = False +is_net90 = False is_mono = False is_netstandard = False if is_ironpython: @@ -30,6 +32,8 @@ is_netcoreapp31 = clr.FrameworkDescription.startswith(".NET Core 3.1") is_net60 = clr.FrameworkDescription.startswith(".NET 6.0") is_net70 = clr.FrameworkDescription.startswith(".NET 7.0") + is_net80 = clr.FrameworkDescription.startswith(".NET 8.0") + is_net90 = clr.FrameworkDescription.startswith(".NET 9.0") is_mono = clr.IsMono is_netstandard = clr.TargetFramework.startswith(".NETStandard") diff --git a/Src/IronPython/Modules/Builtin.cs b/Src/IronPython/Modules/Builtin.cs index 3dad01e67..6d21a52f1 100644 --- a/Src/IronPython/Modules/Builtin.cs +++ b/Src/IronPython/Modules/Builtin.cs @@ -1294,7 +1294,7 @@ private static void PrintHelper(CodeContext/*!*/ context, string/*!*/ sep, strin line = PythonOps.ReadLineFromSrc(context, context.LanguageContext.SystemStandardIn) as string; } - if (line != null && line.EndsWith("\n", StringComparison.Ordinal)) return line.Substring(0, line.Length - 1); + if (line != null && line.EndsWith('\n')) return line.Substring(0, line.Length - 1); return line; } diff --git a/Src/IronPython/Modules/unicodedata.cs b/Src/IronPython/Modules/unicodedata.cs index 2f13b56e6..d6b08a8e1 100644 --- a/Src/IronPython/Modules/unicodedata.cs +++ b/Src/IronPython/Modules/unicodedata.cs @@ -391,7 +391,7 @@ private void BuildDatabase(StreamReader data) { private void BuildNameLookup() { var lookup = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (var c in database) { - if (c.Value.Name.StartsWith("<", StringComparison.Ordinal)) continue; + if (c.Value.Name.StartsWith('<')) continue; lookup[c.Value.Name] = c.Key; foreach (var alias in c.Value.Aliases) { lookup[alias] = c.Key; diff --git a/Src/IronPython/Runtime/Binding/MetaPythonType.Calls.cs b/Src/IronPython/Runtime/Binding/MetaPythonType.Calls.cs index 71565a413..c61c530fa 100644 --- a/Src/IronPython/Runtime/Binding/MetaPythonType.Calls.cs +++ b/Src/IronPython/Runtime/Binding/MetaPythonType.Calls.cs @@ -443,7 +443,7 @@ public ConstructorNewAdapter(ArgumentValues/*!*/ ai, PythonType/*!*/ creating, P return binder.CallMethod( resolve, - _creating.UnderlyingSystemType.GetConstructors(), + PythonTypeOps.GetConstructors(_creating.UnderlyingSystemType, binder.PrivateBinding), Arguments.Self.Restrictions, _creating.Name ); diff --git a/Src/IronPython/Runtime/Binding/PythonBinder.cs b/Src/IronPython/Runtime/Binding/PythonBinder.cs index 8b287a927..50ae3404b 100644 --- a/Src/IronPython/Runtime/Binding/PythonBinder.cs +++ b/Src/IronPython/Runtime/Binding/PythonBinder.cs @@ -761,7 +761,8 @@ internal static void AssertNotExtensionType(Type t) { res[typeof(char)] = new Type[] { typeof(CharOps) }; res[typeof(decimal)] = new Type[] { typeof(DecimalOps) }; res[typeof(float)] = new Type[] { typeof(SingleOps) }; - + res[typeof(DateTime)] = new Type[] { typeof(DateTimeOps) }; + return res; } diff --git a/Src/IronPython/Runtime/Binding/PythonExtensionBinder.cs b/Src/IronPython/Runtime/Binding/PythonExtensionBinder.cs index 31be3aad7..276366231 100644 --- a/Src/IronPython/Runtime/Binding/PythonExtensionBinder.cs +++ b/Src/IronPython/Runtime/Binding/PythonExtensionBinder.cs @@ -65,7 +65,9 @@ internal static bool IsApplicableExtensionMethod(Type instanceType, Type extensi Type[] inferredTypes = new Type[genArgs.Length]; for (int i = 0; i < genArgs.Length; i++) { - if ((inferredTypes[i] = TypeInferer.GetInferedType(genArgs[i], extensionMethodThisType, instanceType, instanceType, binding)) == null) { + var genArg = genArgs[i]; + // https://github.com/IronLanguages/ironpython3/issues/1796 + if (!genArg.IsGenericParameter || (inferredTypes[i] = TypeInferer.GetInferedType(genArg, extensionMethodThisType, instanceType, instanceType, binding)) == null) { inferredTypes = null; break; } diff --git a/Src/IronPython/Runtime/LiteralParser.cs b/Src/IronPython/Runtime/LiteralParser.cs index 39952d139..25006489f 100644 --- a/Src/IronPython/Runtime/LiteralParser.cs +++ b/Src/IronPython/Runtime/LiteralParser.cs @@ -953,9 +953,9 @@ private static double ParseFloatNoCatch(string text, bool replaceUnicode = true) try { res = double.Parse(s, NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture); } catch (OverflowException) { - res = text.lstrip().StartsWith("-", StringComparison.Ordinal) ? Double.NegativeInfinity : Double.PositiveInfinity; + res = text.lstrip().StartsWith('-') ? Double.NegativeInfinity : Double.PositiveInfinity; } - return (res == 0.0 && text.lstrip().StartsWith("-", StringComparison.Ordinal)) ? DoubleOps.NegativeZero : res; + return (res == 0.0 && text.lstrip().StartsWith('-')) ? DoubleOps.NegativeZero : res; } } @@ -990,7 +990,7 @@ public static Complex ParseComplex(string s) { string text = s.Trim().ToLowerInvariant(); // remove 1 layer of parens - if (text.StartsWith("(", StringComparison.Ordinal) && text.EndsWith(")", StringComparison.Ordinal)) { + if (text.StartsWith('(') && text.EndsWith(')')) { text = text.Substring(1, text.Length - 2); } diff --git a/Src/IronPython/Runtime/NewStringFormatter.cs b/Src/IronPython/Runtime/NewStringFormatter.cs index f7f84500c..84ca824ab 100644 --- a/Src/IronPython/Runtime/NewStringFormatter.cs +++ b/Src/IronPython/Runtime/NewStringFormatter.cs @@ -131,7 +131,7 @@ private StringFormatParser(string/*!*/ text) { if (_index == -1) { // no more formats, send the remaining text. yield return PythonTuple.MakeTuple( - _str.Substring(lastTextStart, _str.Length - lastTextStart), + _str.Substring(lastTextStart), null, null, null); diff --git a/Src/IronPython/Runtime/Operations/CharOps.cs b/Src/IronPython/Runtime/Operations/CharOps.cs index 3c1774e8f..10e76d84d 100644 --- a/Src/IronPython/Runtime/Operations/CharOps.cs +++ b/Src/IronPython/Runtime/Operations/CharOps.cs @@ -35,6 +35,8 @@ public static object __new__(PythonType cls, char value) { public static string __repr__(char self) => StringOps.__repr__(char.ToString(self)); + public static PythonTuple __getnewargs__(char self) => PythonTuple.MakeTuple(char.ToString(self)); + public static int __hash__(char self) => char.ToString(self).GetHashCode(); public static int __index__(char self) => self; diff --git a/Src/IronPython/Runtime/Operations/ComOps.cs b/Src/IronPython/Runtime/Operations/ComOps.cs index 3956074f2..53d81703a 100644 --- a/Src/IronPython/Runtime/Operations/ComOps.cs +++ b/Src/IronPython/Runtime/Operations/ComOps.cs @@ -20,7 +20,9 @@ public static class ComOps { } [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00020400-0000-0000-C000-000000000046")] +#pragma warning disable SYSLIB1096 // Convert to 'GeneratedComInterface' private interface IDispatch { +#pragma warning restore SYSLIB1096 // Convert to 'GeneratedComInterface' int GetTypeInfoCount(); [return: MarshalAs(UnmanagedType.Interface)] ITypeInfo GetTypeInfo([In, MarshalAs(UnmanagedType.U4)] int iTInfo, [In, MarshalAs(UnmanagedType.U4)] int lcid); diff --git a/Src/IronPython/Runtime/Operations/DBNullOps.cs b/Src/IronPython/Runtime/Operations/DBNullOps.cs index 364f50e56..f2b1628b7 100644 --- a/Src/IronPython/Runtime/Operations/DBNullOps.cs +++ b/Src/IronPython/Runtime/Operations/DBNullOps.cs @@ -6,8 +6,15 @@ using System; +using Microsoft.Scripting.Runtime; + namespace IronPython.Runtime.Operations { public static class DBNullOps { + [StaticExtensionMethod] + public static object __new__(object cls) { + return DBNull.Value; + } + public static bool __bool__(DBNull value) { return false; } diff --git a/Src/IronPython/Runtime/Operations/DateTimeOps.cs b/Src/IronPython/Runtime/Operations/DateTimeOps.cs new file mode 100644 index 000000000..83b8d6fd5 --- /dev/null +++ b/Src/IronPython/Runtime/Operations/DateTimeOps.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +#nullable enable + +using System; +using System.Numerics; + +namespace IronPython.Runtime.Operations { + public static class DateTimeOps { + public static PythonTuple __getnewargs__(DateTime self) => PythonTuple.MakeTuple((BigInteger)self.Ticks, self.Kind); + } +} diff --git a/Src/IronPython/Runtime/Operations/DecimalOps.cs b/Src/IronPython/Runtime/Operations/DecimalOps.cs index 3adeb1df3..28a6ee853 100644 --- a/Src/IronPython/Runtime/Operations/DecimalOps.cs +++ b/Src/IronPython/Runtime/Operations/DecimalOps.cs @@ -17,6 +17,13 @@ public static class DecimalOps { public static string __repr__(decimal x) => x.ToString(CultureInfo.InvariantCulture); + public static PythonTuple __getnewargs__(decimal self) { + var bits = decimal.GetBits(self); + var sign = bits[3] < 0; + var scale = unchecked((byte)(bits[3] >> 16)); + return PythonTuple.MakeTuple(bits[0], bits[1], bits[2], sign, scale); + } + [SpecialName] public static bool LessThan(decimal x, decimal y) => x < y; [SpecialName] diff --git a/Src/IronPython/Runtime/Operations/EnumOps.cs b/Src/IronPython/Runtime/Operations/EnumOps.cs index 3313c09e2..6c0085772 100644 --- a/Src/IronPython/Runtime/Operations/EnumOps.cs +++ b/Src/IronPython/Runtime/Operations/EnumOps.cs @@ -7,6 +7,9 @@ using System; using System.Runtime.CompilerServices; +using IronPython.Runtime.Types; + +using Microsoft.Scripting.Runtime; using Microsoft.Scripting.Utils; namespace IronPython.Runtime.Operations { @@ -50,6 +53,14 @@ public static object OnesComplement(object self) { throw PythonOps.ValueError("one's complement cannot be applied to {0}", self.GetType()); } + + [StaticExtensionMethod] + public static object __new__(PythonType cls, object value) { + // Note that this method is not required to construct enums but useful for serialization + if (!cls.UnderlyingSystemType.IsEnum) throw PythonOps.TypeError("Enum.__new__: first argument must be an Enum type."); + return Enum.ToObject(cls.UnderlyingSystemType, value); + } + public static bool __bool__(object self) { if (self is Enum) { Type selfType = self.GetType(); @@ -78,5 +89,7 @@ public static string __repr__(object self) { return $""; } + + public static object __getnewargs__(Enum self) => PythonTuple.MakeTuple(Convert.ChangeType(self, Enum.GetUnderlyingType(self.GetType()))); } } diff --git a/Src/IronPython/Runtime/Operations/FloatOps.Generated.cs b/Src/IronPython/Runtime/Operations/FloatOps.Generated.cs index ea2e1775f..113d646c0 100644 --- a/Src/IronPython/Runtime/Operations/FloatOps.Generated.cs +++ b/Src/IronPython/Runtime/Operations/FloatOps.Generated.cs @@ -32,6 +32,8 @@ public static partial class SingleOps { public static bool __bool__(Single x) => (x != 0); + public static PythonTuple __getnewargs__(Single self) => PythonTuple.MakeTuple(unchecked((double)self)); + public static object __trunc__(Single x) { if (x >= int.MaxValue || x <= int.MinValue) { return (BigInteger)x; diff --git a/Src/IronPython/Runtime/Operations/IntOps.Generated.cs b/Src/IronPython/Runtime/Operations/IntOps.Generated.cs index 5c6d91640..4a6c512df 100644 --- a/Src/IronPython/Runtime/Operations/IntOps.Generated.cs +++ b/Src/IronPython/Runtime/Operations/IntOps.Generated.cs @@ -95,6 +95,8 @@ public static object Abs(SByte x) { public static string __repr__(SByte x) => x.ToString(CultureInfo.InvariantCulture); + public static PythonTuple __getnewargs__(SByte self) => PythonTuple.MakeTuple(unchecked((int)self)); + public static SByte __trunc__(SByte x) => x; public static int __int__(SByte x) => unchecked((int)x); @@ -366,6 +368,8 @@ public static object __new__(PythonType cls, object value) { public static string __repr__(Byte x) => x.ToString(CultureInfo.InvariantCulture); + public static PythonTuple __getnewargs__(Byte self) => PythonTuple.MakeTuple(unchecked((int)self)); + public static Byte __trunc__(Byte x) => x; public static int __int__(Byte x) => unchecked((int)x); @@ -739,6 +743,8 @@ public static object Abs(Int16 x) { public static string __repr__(Int16 x) => x.ToString(CultureInfo.InvariantCulture); + public static PythonTuple __getnewargs__(Int16 self) => PythonTuple.MakeTuple(unchecked((int)self)); + public static Int16 __trunc__(Int16 x) => x; public static int __int__(Int16 x) => unchecked((int)x); @@ -1015,6 +1021,8 @@ public static object __new__(PythonType cls, object value) { public static string __repr__(UInt16 x) => x.ToString(CultureInfo.InvariantCulture); + public static PythonTuple __getnewargs__(UInt16 self) => PythonTuple.MakeTuple(unchecked((int)self)); + public static UInt16 __trunc__(UInt16 x) => x; public static int __int__(UInt16 x) => unchecked((int)x); @@ -1398,6 +1406,8 @@ public static object Abs(Int32 x) { public static string __repr__(Int32 x) => x.ToString(CultureInfo.InvariantCulture); + public static PythonTuple __getnewargs__(Int32 self) => PythonTuple.MakeTuple(unchecked((int)self)); + public static Int32 __trunc__(Int32 x) => x; public static int __int__(Int32 x) => unchecked((int)x); @@ -1649,6 +1659,8 @@ public static object __new__(PythonType cls, object value) { public static string __repr__(UInt32 x) => x.ToString(CultureInfo.InvariantCulture); + public static PythonTuple __getnewargs__(UInt32 self) => PythonTuple.MakeTuple(unchecked((BigInteger)self)); + public static UInt32 __trunc__(UInt32 x) => x; public static BigInteger __int__(UInt32 x) => unchecked((BigInteger)x); @@ -2032,6 +2044,8 @@ public static object Abs(Int64 x) { public static string __repr__(Int64 x) => x.ToString(CultureInfo.InvariantCulture); + public static PythonTuple __getnewargs__(Int64 self) => PythonTuple.MakeTuple(unchecked((BigInteger)self)); + public static Int64 __trunc__(Int64 x) => x; public static BigInteger __int__(Int64 x) => unchecked((BigInteger)x); @@ -2306,6 +2320,8 @@ public static object __new__(PythonType cls, object value) { public static string __repr__(UInt64 x) => x.ToString(CultureInfo.InvariantCulture); + public static PythonTuple __getnewargs__(UInt64 self) => PythonTuple.MakeTuple(unchecked((BigInteger)self)); + public static UInt64 __trunc__(UInt64 x) => x; public static BigInteger __int__(UInt64 x) => unchecked((BigInteger)x); diff --git a/Src/IronPython/Runtime/Operations/IntPtrOps.cs b/Src/IronPython/Runtime/Operations/IntPtrOps.cs index 695347549..579bd4b08 100644 --- a/Src/IronPython/Runtime/Operations/IntPtrOps.cs +++ b/Src/IronPython/Runtime/Operations/IntPtrOps.cs @@ -59,6 +59,8 @@ public static object __new__(PythonType cls, object value) { #region Unary Operations + public static PythonTuple __getnewargs__(IntPtr self) => PythonTuple.MakeTuple(unchecked((BigInteger)(nint)self)); + public static BigInteger __index__(IntPtr x) => unchecked((BigInteger)(nint)x); #endregion diff --git a/Src/IronPython/Runtime/Operations/PythonOps.cs b/Src/IronPython/Runtime/Operations/PythonOps.cs index 689e9ebf2..380c5006f 100644 --- a/Src/IronPython/Runtime/Operations/PythonOps.cs +++ b/Src/IronPython/Runtime/Operations/PythonOps.cs @@ -4222,6 +4222,7 @@ public static List PushFrame(CodeContext/*!*/ context, FunctionCo } internal static LightLambdaExpression ToGenerator(this LightLambdaExpression code, bool shouldInterpret, bool debuggable, int compilationThreshold) { +#pragma warning disable CA2263 // Prefer generic overload when type is known return Utils.LightLambda( typeof(object), code.Type, @@ -4229,6 +4230,7 @@ internal static LightLambdaExpression ToGenerator(this LightLambdaExpression cod code.Name, code.Parameters ); +#pragma warning restore CA2263 // Prefer generic overload when type is known } public static void UpdateStackTrace(Exception e, CodeContext context, FunctionCode funcCode, int line) { diff --git a/Src/IronPython/Runtime/Operations/UIntPtrOps.cs b/Src/IronPython/Runtime/Operations/UIntPtrOps.cs index f645643e5..dabdba124 100644 --- a/Src/IronPython/Runtime/Operations/UIntPtrOps.cs +++ b/Src/IronPython/Runtime/Operations/UIntPtrOps.cs @@ -59,6 +59,8 @@ public static object __new__(PythonType cls, object value) { #region Unary Operations + public static PythonTuple __getnewargs__(UIntPtr self) => PythonTuple.MakeTuple(unchecked((BigInteger)(nuint)self)); + public static BigInteger __index__(UIntPtr x) => unchecked((BigInteger)(nuint)x); #endregion diff --git a/Src/IronPython/Runtime/TypecodeOps.cs b/Src/IronPython/Runtime/TypecodeOps.cs index 7a60973c1..e11e97ae1 100644 --- a/Src/IronPython/Runtime/TypecodeOps.cs +++ b/Src/IronPython/Runtime/TypecodeOps.cs @@ -138,6 +138,7 @@ public static bool TryGetFromBytes(char typecode, ReadOnlySpan bytes, [Not } } +#pragma warning disable CS9191 // The 'ref' modifier for an argument corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead. public static bool TryGetBytes(char typecode, object obj, Span dest) { switch (typecode) { case 'c': @@ -205,6 +206,7 @@ public static bool TryGetBytes(char typecode, object obj, Span dest) { return false; } } +#pragma warning restore CS9191 // The 'ref' modifier for an argument corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead. /// /// Checks if the given value does overflow a single element field with the diff --git a/Src/IronPython/Runtime/Types/BuiltinFunctionOverloadMapper.cs b/Src/IronPython/Runtime/Types/BuiltinFunctionOverloadMapper.cs index 452b0517e..bdacd5e3b 100644 --- a/Src/IronPython/Runtime/Types/BuiltinFunctionOverloadMapper.cs +++ b/Src/IronPython/Runtime/Types/BuiltinFunctionOverloadMapper.cs @@ -130,7 +130,7 @@ public void ThrowOverloadException(Type[] sig, IList targets) { System.Text.StringBuilder sigInfo = new System.Text.StringBuilder(); sigInfo.Append((targets.Count > 0 ? targets[0].Name : "") + "["); foreach (var type in sig) { - if (!sigInfo.ToString().EndsWith("[", StringComparison.Ordinal)) { + if (!sigInfo.ToString().EndsWith('[')) { sigInfo.Append(", "); } @@ -148,7 +148,7 @@ public void ThrowOverloadException(Type[] sig, IList targets) { possibleOverloads.Append("["); foreach (var param in overload.GetParameters()) { - if (!possibleOverloads.ToString().EndsWith("[", StringComparison.Ordinal)) { + if (!possibleOverloads.ToString().EndsWith('[')) { possibleOverloads.Append(", "); } possibleOverloads.Append(param.ParameterType.Name); diff --git a/Src/IronPython/Runtime/Types/DocBuilder.cs b/Src/IronPython/Runtime/Types/DocBuilder.cs index 0f958bb29..e2aca6332 100644 --- a/Src/IronPython/Runtime/Types/DocBuilder.cs +++ b/Src/IronPython/Runtime/Types/DocBuilder.cs @@ -504,7 +504,7 @@ private static void AppendTypeFormat(Type curType, StringBuilder res, ParameterI res.Append('}'); } else { if (pi != null) { - if((pi.IsOut || pi.ParameterType.IsByRef) && curType.FullName.EndsWith("&", StringComparison.Ordinal)) { + if((pi.IsOut || pi.ParameterType.IsByRef) && curType.FullName.EndsWith('&')) { res.Append(curType.FullName.Replace("&", "@")); } else { res.Append(curType.FullName); diff --git a/Src/IronPython/Runtime/Types/PythonType.cs b/Src/IronPython/Runtime/Types/PythonType.cs index 6e774c591..77e70c573 100644 --- a/Src/IronPython/Runtime/Types/PythonType.cs +++ b/Src/IronPython/Runtime/Types/PythonType.cs @@ -580,6 +580,7 @@ public static object Get__module__(CodeContext/*!*/ context, PythonType self) { pts.TryGetValue(context, self, DynamicHelpers.GetPythonType(self), out res)) { return res; } + if (self.IsSystemType && !self.IsPythonType) return self.UnderlyingSystemType.Namespace; return PythonTypeOps.GetModuleName(context, self.UnderlyingSystemType); } diff --git a/Src/IronPython/SerializationStubs.cs b/Src/IronPython/SerializationStubs.cs new file mode 100644 index 000000000..f86e2017c --- /dev/null +++ b/Src/IronPython/SerializationStubs.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the Apache 2.0 license. +// See the LICENSE file in the project root for more information. + +#if !FEATURE_SERIALIZATION + +using System; +using System.Diagnostics; + +namespace IronPython { + [Conditional("STUB")] + internal class SerializableAttribute : Attribute { + } + + [Conditional("STUB")] + internal class NonSerializedAttribute : Attribute { + } + + namespace Runtime { + internal interface ISerializable { + } + + internal interface IDeserializationCallback { + } + } + + internal class SerializationException : Exception { + } +} + +#endif diff --git a/Src/IronPython/StringExtensions.cs b/Src/IronPython/StringExtensions.cs new file mode 100644 index 000000000..acbc2fbe5 --- /dev/null +++ b/Src/IronPython/StringExtensions.cs @@ -0,0 +1,15 @@ +using System; + +namespace IronPython { + internal static class StringExtensions { +#if !NETCOREAPP + public static bool EndsWith(this string str, char value) { + return str.EndsWith(value.ToString(), StringComparison.Ordinal); + } + + public static bool StartsWith(this string str, char value) { + return str.StartsWith(value.ToString(), StringComparison.Ordinal); + } +#endif + } +} diff --git a/Src/IronPythonConsole/IronPythonConsole.csproj b/Src/IronPythonConsole/IronPythonConsole.csproj index 8dc8f7bc2..a933ddd3f 100644 --- a/Src/IronPythonConsole/IronPythonConsole.csproj +++ b/Src/IronPythonConsole/IronPythonConsole.csproj @@ -1,7 +1,7 @@  - net462;netcoreapp3.1;net6.0;net7.0 + net462;netcoreapp3.1;net6.0;net8.0 false Exe diff --git a/Src/IronPythonTest/Cases/CPythonCases.cs b/Src/IronPythonTest/Cases/CPythonCases.cs index 90f740924..f3d568064 100644 --- a/Src/IronPythonTest/Cases/CPythonCases.cs +++ b/Src/IronPythonTest/Cases/CPythonCases.cs @@ -18,11 +18,12 @@ public override int Test(TestInfo testcase) { internal class CPythonCaseGenerator : CommonCaseGenerator { protected override IEnumerable GetTests() { + var libFolder = Path.Combine("Src", "StdLib", "Lib"); return GetFilenames(new [] { - System.Tuple.Create(category, Path.Combine("Src", "StdLib", "Lib", "test")), - System.Tuple.Create($"{category}.ctypes", Path.Combine("Src", "StdLib", "Lib", "ctypes", "test")), - System.Tuple.Create($"{category}.distutils", Path.Combine("Src", "StdLib", "Lib", "distutils", "tests")), - System.Tuple.Create($"{category}.unittest", Path.Combine("Src", "StdLib", "Lib", "unittest", "test")), + System.Tuple.Create(category, Path.Combine(libFolder, "test")), + System.Tuple.Create($"{category}.ctypes", Path.Combine(libFolder, "ctypes", "test")), + System.Tuple.Create($"{category}.distutils", Path.Combine(libFolder, "distutils", "tests")), + System.Tuple.Create($"{category}.unittest", Path.Combine(libFolder, "unittest", "test")), }) .OrderBy(testcase => testcase.Name); diff --git a/Src/IronPythonTest/Cases/IronPythonCases.cs b/Src/IronPythonTest/Cases/IronPythonCases.cs index 719cffd45..2cd431625 100644 --- a/Src/IronPythonTest/Cases/IronPythonCases.cs +++ b/Src/IronPythonTest/Cases/IronPythonCases.cs @@ -19,7 +19,7 @@ public override int Test(TestInfo testcase) { internal class IronPythonCaseGenerator : CommonCaseGenerator { protected override IEnumerable GetTests() { return GetFilenames(new[] { - System.Tuple.Create(category, Path.Combine("Tests")), + System.Tuple.Create(category, "Tests"), System.Tuple.Create($"{category}.scripts", Path.Combine("Src", "Scripts")), }) .OrderBy(testcase => testcase.Name); diff --git a/Src/IronPythonTest/EncodingTest.cs b/Src/IronPythonTest/EncodingTest.cs index 53fab617a..7864f0a12 100644 --- a/Src/IronPythonTest/EncodingTest.cs +++ b/Src/IronPythonTest/EncodingTest.cs @@ -58,7 +58,7 @@ public class Utf8BrokenTest { [SetUp] public void SetUp() { - // 12 bytes: two valid UTF-8 2-byte chars, one non-decodable byte, + // 12 bytes: two valid UTF-8 2-byte chars, one non-decodable byte, // one UTF-8 2-byte char with a non-decodable byte inserted in between the UTF-8 bytes // and final valid UTF-8 2-byte char _bytes = "\xd0\x9f\xd0\xb8\x80\xd1\xff\x82\xd0\xbe\xd0\xbd".AsBytes(); @@ -77,13 +77,13 @@ private static void TestRoundTrip(Encoding enc, byte[] bytes) { char[] chars1 = new char[penc.GetCharCount(bytes)]; penc.GetChars(bytes, 0, bytes.Length, chars1, 0); char[] chars2 = penc.GetChars(bytes); - Assert.AreEqual(chars1, chars2); + Assert.That(chars1, Is.EqualTo(chars2)); byte[] bytes1 = penc.GetBytes(chars1); byte[] bytes2 = new byte[penc.GetByteCount(chars1, 0, chars1.Length)]; penc.GetBytes(chars1, 0, chars1.Length, bytes2, 0); - Assert.AreEqual(bytes1, bytes2); - Assert.AreEqual(bytes, bytes1); + Assert.That(bytes1, Is.EqualTo(bytes2)); + Assert.That(bytes, Is.EqualTo(bytes1)); } #endregion @@ -113,7 +113,7 @@ public void TestCompare256WithAscii() { Encoding penc = new PythonSurrogateEscapeEncoding(Encoding.ASCII); char[] chars = penc.GetChars(bytes); string python_chars = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\udc80\udc81\udc82\udc83\udc84\udc85\udc86\udc87\udc88\udc89\udc8a\udc8b\udc8c\udc8d\udc8e\udc8f\udc90\udc91\udc92\udc93\udc94\udc95\udc96\udc97\udc98\udc99\udc9a\udc9b\udc9c\udc9d\udc9e\udc9f\udca0\udca1\udca2\udca3\udca4\udca5\udca6\udca7\udca8\udca9\udcaa\udcab\udcac\udcad\udcae\udcaf\udcb0\udcb1\udcb2\udcb3\udcb4\udcb5\udcb6\udcb7\udcb8\udcb9\udcba\udcbb\udcbc\udcbd\udcbe\udcbf\udcc0\udcc1\udcc2\udcc3\udcc4\udcc5\udcc6\udcc7\udcc8\udcc9\udcca\udccb\udccc\udccd\udcce\udccf\udcd0\udcd1\udcd2\udcd3\udcd4\udcd5\udcd6\udcd7\udcd8\udcd9\udcda\udcdb\udcdc\udcdd\udcde\udcdf\udce0\udce1\udce2\udce3\udce4\udce5\udce6\udce7\udce8\udce9\udcea\udceb\udcec\udced\udcee\udcef\udcf0\udcf1\udcf2\udcf3\udcf4\udcf5\udcf6\udcf7\udcf8\udcf9\udcfa\udcfb\udcfc\udcfd\udcfe\udcff"; - Assert.AreEqual(python_chars, chars); + Assert.That(chars, Is.EqualTo(python_chars)); } @@ -122,7 +122,7 @@ public void TestCompare256WithLatin1() { Encoding penc = new PythonSurrogateEscapeEncoding(StringOps.Latin1Encoding); char[] chars = penc.GetChars(bytes); string python_chars = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0¡¢£¤¥¦§¨©ª«¬\xad®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"; - Assert.AreEqual(python_chars, chars); + Assert.That(chars, Is.EqualTo(python_chars)); } @@ -132,24 +132,24 @@ public void TestCompare256WithUtf8() { Encoding penc = new PythonSurrogateEscapeEncoding(Encoding.UTF8); char[] chars = penc.GetChars(bytes); string python_chars = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\udc80\udc81\udc82\udc83\udc84\udc85\udc86\udc87\udc88\udc89\udc8a\udc8b\udc8c\udc8d\udc8e\udc8f\udc90\udc91\udc92\udc93\udc94\udc95\udc96\udc97\udc98\udc99\udc9a\udc9b\udc9c\udc9d\udc9e\udc9f\udca0\udca1\udca2\udca3\udca4\udca5\udca6\udca7\udca8\udca9\udcaa\udcab\udcac\udcad\udcae\udcaf\udcb0\udcb1\udcb2\udcb3\udcb4\udcb5\udcb6\udcb7\udcb8\udcb9\udcba\udcbb\udcbc\udcbd\udcbe\udcbf\udcc0\udcc1\udcc2\udcc3\udcc4\udcc5\udcc6\udcc7\udcc8\udcc9\udcca\udccb\udccc\udccd\udcce\udccf\udcd0\udcd1\udcd2\udcd3\udcd4\udcd5\udcd6\udcd7\udcd8\udcd9\udcda\udcdb\udcdc\udcdd\udcde\udcdf\udce0\udce1\udce2\udce3\udce4\udce5\udce6\udce7\udce8\udce9\udcea\udceb\udcec\udced\udcee\udcef\udcf0\udcf1\udcf2\udcf3\udcf4\udcf5\udcf6\udcf7\udcf8\udcf9\udcfa\udcfb\udcfc\udcfd\udcfe\udcff"; - Assert.AreEqual(python_chars, chars); + Assert.That(chars, Is.EqualTo(python_chars)); } // Compare Windows-1252 (Western European Windows, variant of ISO-8859-1) handling with CPython results [Test] public void TestCompare256WithWindows1252() { Encoding penc = new PythonSurrogateEscapeEncoding(Encoding.GetEncoding(1252)); - Assert.AreEqual("windows-1252", penc.WebName.ToLowerInvariant()); + Assert.That(penc.WebName.ToLowerInvariant(), Is.EqualTo("windows-1252")); char[] chars = penc.GetChars(bytes); string python_chars = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f€\udc81‚ƒ„…†‡ˆ‰Š‹Œ\udc8dŽ\udc8f\udc90‘’“”•–—˜™š›œ\udc9džŸ\xa0¡¢£¤¥¦§¨©ª«¬\xad®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"; string encoded = new string(chars); - Assert.AreEqual(python_chars.Length, encoded.Length); + Assert.That(encoded.Length, Is.EqualTo(python_chars.Length)); for (int i = 0; i < encoded.Length; i++) { if (encoded[i] != python_chars[i]) { // Known differences between Windows and Python (Unicode) implementation of Windows-1252 // https://en.wikipedia.org/wiki/Windows-1252 - CollectionAssert.Contains(new[] { 0x81, 0x8d, 0x8f, 0x90, 0x9d }, i); + Assert.That(new[] { 0x81, 0x8d, 0x8f, 0x90, 0x9d }, Has.Member(i)); } } } @@ -158,12 +158,12 @@ public void TestCompare256WithWindows1252() { [Test] public void TestCompare256WithIso8859_1() { Encoding penc = new PythonSurrogateEscapeEncoding(Encoding.GetEncoding(28591)); - Assert.AreEqual("iso-8859-1", penc.WebName); + Assert.That(penc.WebName, Is.EqualTo("iso-8859-1")); char[] chars = penc.GetChars(bytes); string python_chars = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0¡¢£¤¥¦§¨©ª«¬\xad®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"; string encoded = new string(chars); - Assert.AreEqual(python_chars, encoded); + Assert.That(encoded, Is.EqualTo(python_chars)); } // Compare UTF-7 handling with CPython results @@ -180,13 +180,13 @@ public void TestCompare256WithUtf7() { // Let's try again without the '+' bytes = bytes.Where(i => i != (byte)'+').ToArray(); char[] chars = penc.GetChars(bytes); - Assert.AreEqual(python_chars, chars); + Assert.That(chars, Is.EqualTo(python_chars)); // Now the encoding part byte[] encoded_bytes = penc.GetBytes(chars); byte[] expected_bytes = "+AAAAAQACAAMABAAFAAYABwAI-\t\n+AAsADA-\r+AA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAf- !\"#$%&'()*,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[+AFw-]^_`abcdefghijklmnopqrstuvwxyz{|}+AH4Af9yA3IHcgtyD3ITchdyG3IfciNyJ3Irci9yM3I3cjtyP3JDckdyS3JPclNyV3Jbcl9yY3Jncmtyb3Jzcndye3J/coNyh3KLco9yk3KXcptyn3Kjcqdyq3KvcrNyt3K7cr9yw3LHcstyz3LTctdy23LfcuNy53Lrcu9y83L3cvty/3MDcwdzC3MPcxNzF3Mbcx9zI3MncytzL3MzczdzO3M/c0NzR3NLc09zU3NXc1tzX3Njc2dza3Nvc3Nzd3N7c39zg3OHc4tzj3OTc5dzm3Ofc6Nzp3Orc69zs3O3c7tzv3PDc8dzy3PPc9Nz13Pbc99z43Pnc+tz73Pzc/dz+3P8-" .Select(c => (byte)c).ToArray(); - Assert.AreEqual(expected_bytes, encoded_bytes); + Assert.That(encoded_bytes, Is.EqualTo(expected_bytes)); // Encoding the given chars with CPython produces the following byte string byte[] python_bytes = "+AAAAAQACAAMABAAFAAYABwAI\t\n+AAsADA\r+AA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAf !\"#$%&'()*,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[+AFw]^_`abcdefghijklmnopqrstuvwxyz{|}+AH4Af9yA3IHcgtyD3ITchdyG3IfciNyJ3Irci9yM3I3cjtyP3JDckdyS3JPclNyV3Jbcl9yY3Jncmtyb3Jzcndye3J/coNyh3KLco9yk3KXcptyn3Kjcqdyq3KvcrNyt3K7cr9yw3LHcstyz3LTctdy23LfcuNy53Lrcu9y83L3cvty/3MDcwdzC3MPcxNzF3Mbcx9zI3MncytzL3MzczdzO3M/c0NzR3NLc09zU3NXc1tzX3Njc2dza3Nvc3Nzd3N7c39zg3OHc4tzj3OTc5dzm3Ofc6Nzp3Orc69zs3O3c7tzv3PDc8dzy3PPc9Nz13Pbc99z43Pnc+tz73Pzc/dz+3P8-" @@ -197,10 +197,10 @@ public void TestCompare256WithUtf7() { // However, they both decode to the same text, although, again, CPython's version cannot be decoded using surrogateescape char[] dotnet_decoded = penc.GetChars(encoded_bytes); char[] python_decoded = utf7.GetChars(python_bytes); - Assert.AreEqual(chars, python_decoded); - Assert.AreEqual(chars, dotnet_decoded); + Assert.That(chars, Is.EqualTo(python_decoded)); + Assert.That(chars, Is.EqualTo(dotnet_decoded)); dotnet_decoded = utf7.GetChars(encoded_bytes); - Assert.AreEqual(chars, dotnet_decoded); + Assert.That(chars, Is.EqualTo(dotnet_decoded)); } // Compare UTF-16 handling with CPython results @@ -210,11 +210,11 @@ public void TestCompare256Utf16() { char[] chars = penc.GetChars(bytes); char[] python_chars = (new[] { 0x0100, 0x0302, 0x0504, 0x0706, 0x0908, 0x0b0a, 0x0d0c, 0x0f0e, 0x1110, 0x1312, 0x1514, 0x1716, 0x1918, 0x1b1a, 0x1d1c, 0x1f1e, 0x2120, 0x2322, 0x2524, 0x2726, 0x2928, 0x2b2a, 0x2d2c, 0x2f2e, 0x3130, 0x3332, 0x3534, 0x3736, 0x3938, 0x3b3a, 0x3d3c, 0x3f3e, 0x4140, 0x4342, 0x4544, 0x4746, 0x4948, 0x4b4a, 0x4d4c, 0x4f4e, 0x5150, 0x5352, 0x5554, 0x5756, 0x5958, 0x5b5a, 0x5d5c, 0x5f5e, 0x6160, 0x6362, 0x6564, 0x6766, 0x6968, 0x6b6a, 0x6d6c, 0x6f6e, 0x7170, 0x7372, 0x7574, 0x7776, 0x7978, 0x7b7a, 0x7d7c, 0x7f7e, 0x8180, 0x8382, 0x8584, 0x8786, 0x8988, 0x8b8a, 0x8d8c, 0x8f8e, 0x9190, 0x9392, 0x9594, 0x9796, 0x9998, 0x9b9a, 0x9d9c, 0x9f9e, 0xa1a0, 0xa3a2, 0xa5a4, 0xa7a6, 0xa9a8, 0xabaa, 0xadac, 0xafae, 0xb1b0, 0xb3b2, 0xb5b4, 0xb7b6, 0xb9b8, 0xbbba, 0xbdbc, 0xbfbe, 0xc1c0, 0xc3c2, 0xc5c4, 0xc7c6, 0xc9c8, 0xcbca, 0xcdcc, 0xcfce, 0xd1d0, 0xd3d2, 0xd5d4, 0xd7d6, 0xdcd8, 0xdcd9, 0x1069dc, 0xdcde, 0xdcdf, 0xe1e0, 0xe3e2, 0xe5e4, 0xe7e6, 0xe9e8, 0xebea, 0xedec, 0xefee, 0xf1f0, 0xf3f2, 0xf5f4, 0xf7f6, 0xf9f8, 0xfbfa, 0xfdfc, 0xfffe }) .SelectMany(i => i <= 0xffff ? ((char)i).ToString() : char.ConvertFromUtf32(i)).ToArray(); - Assert.AreEqual(python_chars, chars); + Assert.That(python_chars, Is.EqualTo(chars)); // byte[] python_bytes = ??? - CPython fails to encode the string it decoded itself; a bug in CPython? byte[] bytes1 = penc.GetBytes(chars); - Assert.AreEqual(bytes, bytes1); + Assert.That(bytes, Is.EqualTo(bytes1)); } } @@ -235,11 +235,11 @@ public void TesWithUtf16() { char[] chars = penc.GetChars(bytes); char[] python_chars = (new[] { 0x0000dcd8, 0x0000dcd9, 0x001069dc, 0x0000dcde, 0x0000dcdf }) .SelectMany(i => i <= 0xffff ? ((char)i).ToString() : char.ConvertFromUtf32(i)).ToArray(); - Assert.AreEqual(python_chars, chars); + Assert.That(python_chars, Is.EqualTo(chars)); // byte[] python_bytes = ??? - CPython fails on encoding the string it decoded itself; a bug in CPython? byte[] bytes1 = penc.GetBytes(chars); - Assert.AreEqual(bytes, bytes1); + Assert.That(bytes, Is.EqualTo(bytes1)); } [Test] @@ -248,11 +248,11 @@ public void TestWithUtf32() { char[] chars = penc.GetChars(bytes); char[] python_chars = (new[] { 0x0000dcd8, 0x0000dcd9, 0x0000dcda, 0x0000dcdb, 0x0000dcdc, 0x0000dcdd, 0x0000dcde, 0x0000dcdf }) .SelectMany(i => i <= 0xffff ? ((char)i).ToString() : char.ConvertFromUtf32(i)).ToArray(); - Assert.AreEqual(python_chars, chars); + Assert.That(python_chars, Is.EqualTo(chars)); // byte[] python_bytes = ??? - CPython fails on encoding the string it decoded itself; a bug in CPython? byte[] bytes1 = penc.GetBytes(chars); - Assert.AreEqual(bytes, bytes1); + Assert.That(bytes, Is.EqualTo(bytes1)); } } @@ -320,21 +320,21 @@ public void SetUp() { [Test] public void TestEndiannessWithUtf16LE() { Encoding penc = new PythonSurrogateEscapeEncoding(Encoding.Unicode); - Assert.AreEqual("\u000a\u0000", penc.GetChars(_bytes1)); - Assert.AreEqual("\u0000\u0a00", penc.GetChars(_bytes2)); + Assert.That("\u000a\u0000", Is.EqualTo(penc.GetChars(_bytes1))); + Assert.That("\u0000\u0a00", Is.EqualTo(penc.GetChars(_bytes2))); } [Test] public void TestEndiannessWithUtf16BE() { Encoding penc = new PythonSurrogateEscapeEncoding(Encoding.BigEndianUnicode); - Assert.AreEqual("\u0a00\u0000", penc.GetChars(_bytes1)); - Assert.AreEqual("\u0000\u000a", penc.GetChars(_bytes2)); + Assert.That("\u0a00\u0000", Is.EqualTo(penc.GetChars(_bytes1))); + Assert.That("\u0000\u000a", Is.EqualTo(penc.GetChars(_bytes2))); } [Test] public void TestEndiannessWithUtf32LE() { Encoding penc = new PythonSurrogateEscapeEncoding(new UTF32Encoding(bigEndian: false, byteOrderMark: false)); - Assert.AreEqual("\u000a", penc.GetChars(_bytes1)); + Assert.That("\u000a", Is.EqualTo(penc.GetChars(_bytes1))); Assert.Throws(() => penc.GetChars(_bytes2)); } @@ -342,7 +342,7 @@ public void TestEndiannessWithUtf32LE() { public void TestEndiannessWithUtf32BE() { Encoding penc = new PythonSurrogateEscapeEncoding(new UTF32Encoding(bigEndian: true, byteOrderMark: false)); Assert.Throws(() => penc.GetChars(_bytes1)); - Assert.AreEqual("\u000a", penc.GetChars(_bytes2)); + Assert.That("\u000a", Is.EqualTo(penc.GetChars(_bytes2))); } } @@ -404,7 +404,7 @@ public void TestAscii() { Encoding penc = new PythonSurrogatePassEncoding(Encoding.ASCII); // clean ASCII - Assert.AreEqual("abc".AsBytes(), penc.GetBytes("abc")); + Assert.That(penc.GetBytes("abc"), Is.EqualTo("abc".AsBytes())); // Attempting to encode surrogates to ASCII will throw an exception. // Note that this is CPython 3.5 behaviour, CPython 3.4 will happily contaminate ASCII with UTF-8 encoded surrogates. @@ -427,13 +427,13 @@ public void TestUtf7() { Encoding penc = new PythonSurrogatePassEncoding(new UTF7Encoding(allowOptionals: true)); // lone high surrogate - Assert.AreEqual("abc+2BA-xyz".AsBytes(), penc.GetBytes("abc\ud810xyz")); + Assert.That(penc.GetBytes("abc\ud810xyz"), Is.EqualTo("abc+2BA-xyz".AsBytes())); // lone low surrogate - Assert.AreEqual("abc+3Ao-xyz".AsBytes(), penc.GetBytes("abc\udc0axyz")); + Assert.That(penc.GetBytes("abc\udc0axyz"), Is.EqualTo("abc+3Ao-xyz".AsBytes())); // invalid surrogate pair (low, high) - Assert.AreEqual("abc+3lHaLw-xyz".AsBytes(), penc.GetBytes("abc\ude51\uda2fxyz")); + Assert.That(penc.GetBytes("abc\ude51\uda2fxyz"), Is.EqualTo("abc+3lHaLw-xyz".AsBytes())); } [Test] @@ -441,13 +441,13 @@ public void TestUtf8() { Encoding penc = new PythonSurrogatePassEncoding(Encoding.UTF8); // lone high surrogate - Assert.AreEqual("abc\xed\xa0\x90xyz".AsBytes(), penc.GetBytes("abc\ud810xyz")); + Assert.That(penc.GetBytes("abc\ud810xyz"), Is.EqualTo("abc\xed\xa0\x90xyz".AsBytes())); // lone low surrogate - Assert.AreEqual("abc\xed\xb0\x8axyz".AsBytes(), penc.GetBytes("abc\udc0axyz")); + Assert.That(penc.GetBytes("abc\udc0axyz"), Is.EqualTo("abc\xed\xb0\x8axyz".AsBytes())); // invalid surrogate pair (low, high) - Assert.AreEqual("abc\xed\xb9\x91\xed\xa8\xafxyz".AsBytes(), penc.GetBytes("abc\ude51\uda2fxyz")); + Assert.That(penc.GetBytes("abc\ude51\uda2fxyz"), Is.EqualTo("abc\xed\xb9\x91\xed\xa8\xafxyz".AsBytes())); } [Test] @@ -455,13 +455,13 @@ public void TestUtf16LE() { Encoding penc = new PythonSurrogatePassEncoding(Encoding.Unicode); // lone high surrogate - Assert.AreEqual("\x10\xd8".AsBytes(), penc.GetBytes("\ud810")); + Assert.That(penc.GetBytes("\ud810"), Is.EqualTo("\x10\xd8".AsBytes())); // lone low surrogate - Assert.AreEqual("\n\xdc".AsBytes(), penc.GetBytes("\udc0a")); + Assert.That(penc.GetBytes("\udc0a"), Is.EqualTo("\n\xdc".AsBytes())); // invalid surrogate pair (low, high) - Assert.AreEqual("Q\xde/\xda".AsBytes(), penc.GetBytes("\ude51\uda2f")); + Assert.That(penc.GetBytes("\ude51\uda2f"), Is.EqualTo("Q\xde/\xda".AsBytes())); } [Test] @@ -469,13 +469,13 @@ public void TestUtf16BE() { Encoding penc = new PythonSurrogatePassEncoding(Encoding.BigEndianUnicode); // lone high surrogate - Assert.AreEqual("\xd8\x10".AsBytes(), penc.GetBytes("\ud810")); + Assert.That(penc.GetBytes("\ud810"), Is.EqualTo("\xd8\x10".AsBytes())); // lone low surrogate - Assert.AreEqual("\xdc\n".AsBytes(), penc.GetBytes("\udc0a")); + Assert.That(penc.GetBytes("\udc0a"), Is.EqualTo("\xdc\n".AsBytes())); // invalid surrogate pair (low, high) - Assert.AreEqual("\xdeQ\xda/".AsBytes(), penc.GetBytes("\ude51\uda2f")); + Assert.That(penc.GetBytes("\ude51\uda2f"), Is.EqualTo("\xdeQ\xda/".AsBytes())); } [Test] @@ -483,13 +483,13 @@ public void TestUtf32LE() { Encoding penc = new PythonSurrogatePassEncoding(new UTF32Encoding(bigEndian: false, byteOrderMark: false)); // lone high surrogate - Assert.AreEqual("\x10\xd8\x00\x00".AsBytes(), penc.GetBytes("\ud810")); + Assert.That(penc.GetBytes("\ud810"), Is.EqualTo("\x10\xd8\x00\x00".AsBytes())); // lone low surrogate - Assert.AreEqual("\n\xdc\x00\x00".AsBytes(), penc.GetBytes("\udc0a")); + Assert.That(penc.GetBytes("\udc0a"), Is.EqualTo("\n\xdc\x00\x00".AsBytes())); // invalid surrogate pair (low, high) - Assert.AreEqual("Q\xde\x00\x00/\xda\x00\x00".AsBytes(), penc.GetBytes("\ude51\uda2f")); + Assert.That(penc.GetBytes("\ude51\uda2f"), Is.EqualTo("Q\xde\x00\x00/\xda\x00\x00".AsBytes())); } [Test] @@ -497,13 +497,13 @@ public void TestUtf32BE() { Encoding penc = new PythonSurrogatePassEncoding(new UTF32Encoding(bigEndian: true, byteOrderMark: false)); // lone high surrogate - Assert.AreEqual("\x00\x00\xd8\x10".AsBytes(), penc.GetBytes("\ud810")); + Assert.That(penc.GetBytes("\ud810"), Is.EqualTo("\x00\x00\xd8\x10".AsBytes())); // lone low surrogate - Assert.AreEqual("\x00\x00\xdc\n".AsBytes(), penc.GetBytes("\udc0a")); + Assert.That(penc.GetBytes("\udc0a"), Is.EqualTo("\x00\x00\xdc\n".AsBytes())); // invalid surrogate pair (low, high) - Assert.AreEqual("\x00\x00\xdeQ\x00\x00\xda/".AsBytes(), penc.GetBytes("\ude51\uda2f")); + Assert.That(penc.GetBytes("\ude51\uda2f"), Is.EqualTo("\x00\x00\xdeQ\x00\x00\xda/".AsBytes())); } } @@ -516,7 +516,7 @@ public void TestAscii() { Encoding penc = new PythonSurrogatePassEncoding(Encoding.ASCII); // clean ASCII - Assert.AreEqual("abc", penc.GetChars("abc".AsBytes())); + Assert.That(penc.GetChars("abc".AsBytes()), Is.EqualTo("abc")); // Attempting to decode surrogates from ASCII will throw an exception. // Note that this is CPython 3.5 behaviour, CPython 3.4 will will blindly extract UTF-8 encoded surrogates from ASCII. @@ -539,13 +539,13 @@ public void TestUtf7() { Encoding penc = new PythonSurrogatePassEncoding(new UTF7Encoding(allowOptionals: true)); // lone high surrogate - Assert.AreEqual("abc\ud810xyz", penc.GetChars("abc+2BA-xyz".AsBytes())); + Assert.That(penc.GetChars("abc+2BA-xyz".AsBytes()), Is.EqualTo("abc\ud810xyz")); // lone low surrogate - Assert.AreEqual("abc\udc0axyz", penc.GetChars("abc+3Ao-xyz".AsBytes())); + Assert.That(penc.GetChars("abc+3Ao-xyz".AsBytes()), Is.EqualTo("abc\udc0axyz")); // invalid surrogate pair (low, high) - Assert.AreEqual("abc\ude51\uda2fxyz", penc.GetChars("abc+3lHaLw-xyz".AsBytes())); + Assert.That(penc.GetChars("abc+3lHaLw-xyz".AsBytes()), Is.EqualTo("abc\ude51\uda2fxyz")); } [Test] @@ -553,16 +553,16 @@ public void TestUtf8() { Encoding penc = new PythonSurrogatePassEncoding(Encoding.UTF8); // lone high surrogate - Assert.AreEqual("abc\ud810xyz", penc.GetChars("abc\xed\xa0\x90xyz".AsBytes())); + Assert.That(penc.GetChars("abc\xed\xa0\x90xyz".AsBytes()), Is.EqualTo("abc\ud810xyz")); // lone low surrogate - Assert.AreEqual("abc\udc0axyz", penc.GetChars("abc\xed\xb0\x8axyz".AsBytes())); + Assert.That(penc.GetChars("abc\xed\xb0\x8axyz".AsBytes()), Is.EqualTo("abc\udc0axyz")); // invalid surrogate pair (low, high) - Assert.AreEqual("abc\ude51\uda2fxyz", penc.GetChars("abc\xed\xb9\x91\xed\xa8\xafxyz".AsBytes())); + Assert.That(penc.GetChars("abc\xed\xb9\x91\xed\xa8\xafxyz".AsBytes()), Is.EqualTo("abc\ude51\uda2fxyz")); // valid surrogate pair (high, low) - Assert.AreEqual("abc\uda2f\ude51xyz", penc.GetChars("abc\xed\xa8\xaf\xed\xb9\x91xyz".AsBytes())); + Assert.That(penc.GetChars("abc\xed\xa8\xaf\xed\xb9\x91xyz".AsBytes()), Is.EqualTo("abc\uda2f\ude51xyz")); var chars = new char[9]; @@ -640,13 +640,13 @@ public void TestUtf16LE() { Encoding penc = new PythonSurrogatePassEncoding(Encoding.Unicode); // lone high surrogate - Assert.AreEqual("\ud810", penc.GetChars("\x10\xd8".AsBytes())); + Assert.That(penc.GetChars("\x10\xd8".AsBytes()), Is.EqualTo("\ud810")); // lone low surrogate - Assert.AreEqual("\udc0a", penc.GetChars("\n\xdc".AsBytes())); + Assert.That(penc.GetChars("\n\xdc".AsBytes()), Is.EqualTo("\udc0a")); // invalid surrogate pair (low, high) - Assert.AreEqual("\ude51\uda2f", penc.GetChars("Q\xde/\xda".AsBytes())); + Assert.That(penc.GetChars("Q\xde/\xda".AsBytes()), Is.EqualTo("\ude51\uda2f")); } [Test] @@ -654,13 +654,13 @@ public void TestUtf16BE() { Encoding penc = new PythonSurrogatePassEncoding(Encoding.BigEndianUnicode); // lone high surrogate - Assert.AreEqual("\ud810", penc.GetChars("\xd8\x10".AsBytes())); + Assert.That(penc.GetChars("\xd8\x10".AsBytes()), Is.EqualTo("\ud810")); // lone low surrogate - Assert.AreEqual("\udc0a", penc.GetChars("\xdc\n".AsBytes())); + Assert.That(penc.GetChars("\xdc\n".AsBytes()), Is.EqualTo("\udc0a")); // invalid surrogate pair (low, high) - Assert.AreEqual("\ude51\uda2f", penc.GetChars("\xdeQ\xda/".AsBytes())); + Assert.That(penc.GetChars("\xdeQ\xda/".AsBytes()), Is.EqualTo("\ude51\uda2f")); } [Test] @@ -668,13 +668,13 @@ public void TestUtf32LE() { Encoding penc = new PythonSurrogatePassEncoding(new UTF32Encoding(bigEndian: false, byteOrderMark: false)); // lone high surrogate - Assert.AreEqual("\ud810", penc.GetChars("\x10\xd8\x00\x00".AsBytes())); + Assert.That(penc.GetChars("\x10\xd8\x00\x00".AsBytes()), Is.EqualTo("\ud810")); // lone low surrogate - Assert.AreEqual("\udc0a", penc.GetChars("\n\xdc\x00\x00".AsBytes())); + Assert.That(penc.GetChars("\n\xdc\x00\x00".AsBytes()), Is.EqualTo("\udc0a")); // invalid surrogate pair (low, high) - Assert.AreEqual("\ude51\uda2f", penc.GetChars("Q\xde\x00\x00/\xda\x00\x00".AsBytes())); + Assert.That(penc.GetChars("Q\xde\x00\x00/\xda\x00\x00".AsBytes()), Is.EqualTo("\ude51\uda2f")); } [Test] @@ -682,13 +682,13 @@ public void TestUtf32BE() { Encoding penc = new PythonSurrogatePassEncoding(new UTF32Encoding(bigEndian: true, byteOrderMark: false)); // lone high surrogate - Assert.AreEqual("\ud810", penc.GetChars("\x00\x00\xd8\x10".AsBytes())); + Assert.That(penc.GetChars("\x00\x00\xd8\x10".AsBytes()), Is.EqualTo("\ud810")); // lone low surrogate - Assert.AreEqual("\udc0a", penc.GetChars("\x00\x00\xdc\n".AsBytes())); + Assert.That(penc.GetChars("\x00\x00\xdc\n".AsBytes()), Is.EqualTo("\udc0a")); // invalid surrogate pair (low, high) - Assert.AreEqual("\ude51\uda2f", penc.GetChars("\x00\x00\xdeQ\x00\x00\xda/".AsBytes())); + Assert.That(penc.GetChars("\x00\x00\xdeQ\x00\x00\xda/".AsBytes()), Is.EqualTo("\ude51\uda2f")); } } @@ -697,7 +697,7 @@ public class IncrementalTests { [Test] public void TestIncrementalWithUtf16() { - // In UTF-16LE: lone low surrogate (invalid) Lone high surrogate (invalid), surrogate pair: high-low (valid), + // In UTF-16LE: lone low surrogate (invalid) Lone high surrogate (invalid), surrogate pair: high-low (valid), var bytes = new byte[] { 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf }; Encoding penc = new PythonSurrogatePassEncoding(Encoding.Unicode); SurrogateTestHelpers.IncrementalTest(penc, bytes, roundTrip: false); @@ -735,7 +735,7 @@ public static void IncrementalTest(Encoding penc, byte[] bytes, bool roundTrip) for (int splitBytesAt = 0; splitBytesAt <= expBytes.Length; splitBytesAt += 1) { // From https://docs.microsoft.com/en-us/dotnet/api/system.text.decoder.getchars?view=netframework-4.5: // The application should call GetCharCount on a block of data immediately before calling GetChars on the same block, - // so that any trailing bytes from the previous block are included in the calculation. + // so that any trailing bytes from the previous block are included in the calculation. var dec = penc.GetDecoder(); char[] chars1 = new char[dec.GetCharCount(expBytes, 0, splitBytesAt, flush: false)]; dec.GetChars(expBytes, 0, splitBytesAt, chars1, 0, flush: false); @@ -743,7 +743,7 @@ public static void IncrementalTest(Encoding penc, byte[] bytes, bool roundTrip) dec.GetChars(expBytes, splitBytesAt, expBytes.Length - splitBytesAt, chars2, 0, flush: true); char[] total_chars = chars1.Concat(chars2).ToArray(); - Assert.AreEqual(expChars, total_chars, "Splitting bytes at {0}", splitBytesAt); + Assert.That(total_chars, Is.EqualTo(expChars), $"Splitting bytes at {splitBytesAt}"); for (int splitCharsAt = 0; splitCharsAt <= total_chars.Length; splitCharsAt += 1) { // From https://docs.microsoft.com/en-us/dotnet/api/system.text.encoder.getbytecount?view=netframework-4.5: @@ -757,7 +757,7 @@ public static void IncrementalTest(Encoding penc, byte[] bytes, bool roundTrip) enc.GetBytes(total_chars, splitCharsAt, total_chars.Length - splitCharsAt, bytes2, 0, flush: true); byte[] total_bytes = bytes1.Concat(bytes2).ToArray(); - Assert.AreEqual(expBytes, total_bytes, "Splitting chars at {0}", splitCharsAt); + Assert.That(total_bytes, Is.EqualTo(expBytes), $"Splitting chars at {splitCharsAt}"); } } } diff --git a/Src/IronPythonTest/EngineTest.cs b/Src/IronPythonTest/EngineTest.cs index cc70bb36d..f6cd8b21f 100644 --- a/Src/IronPythonTest/EngineTest.cs +++ b/Src/IronPythonTest/EngineTest.cs @@ -260,7 +260,7 @@ private void TestRuntimes(Dictionary options, ScriptRuntime[] ru private void TestEngine(ScriptEngine scriptEngine, Dictionary options) { // basic smoke tests that the engine is alive and working - Assert.AreEqual((int)(object)scriptEngine.Execute("42"), 42); + Assert.That(42, Is.EqualTo((int)(object)scriptEngine.Execute("42"))); if (options != null) { // TODO: @@ -272,18 +272,18 @@ private void TestEngine(ScriptEngine scriptEngine, Dictionary op ); #pragma warning restore 618 - Assert.AreEqual(po.StripDocStrings, true); - Assert.AreEqual(po.Optimize, true); - Assert.AreEqual(po.RecursionLimit, 42); - Assert.AreEqual(po.WarningFilters[0], "warnonme"); + Assert.That(true, Is.EqualTo(po.StripDocStrings)); + Assert.That(true, Is.EqualTo(po.Optimize)); + Assert.That(42, Is.EqualTo(po.RecursionLimit)); + Assert.That("warnonme", Is.EqualTo(po.WarningFilters[0])); } - Assert.AreEqual(Python.GetSysModule(scriptEngine).GetVariable("platform"), "cli"); - Assert.AreEqual(Python.GetBuiltinModule(scriptEngine).GetVariable("True"), true); + Assert.That("cli", Is.EqualTo(Python.GetSysModule(scriptEngine).GetVariable("platform"))); + Assert.That(true, Is.EqualTo(Python.GetBuiltinModule(scriptEngine).GetVariable("True"))); if (System.Environment.OSVersion.Platform == System.PlatformID.Unix) { - Assert.AreEqual(Python.ImportModule(scriptEngine, "posix").GetVariable("F_OK"), 0); + Assert.That(0, Is.EqualTo(Python.ImportModule(scriptEngine, "posix").GetVariable("F_OK"))); } else { - Assert.AreEqual(Python.ImportModule(scriptEngine, "nt").GetVariable("F_OK"), 0); + Assert.That(0, Is.EqualTo(Python.ImportModule(scriptEngine, "nt").GetVariable("F_OK"))); } Assert.Throws(() => { Python.ImportModule(scriptEngine, "non_existant_module"); @@ -293,19 +293,19 @@ private void TestEngine(ScriptEngine scriptEngine, Dictionary op private void TestRuntime(ScriptRuntime runtime, Dictionary options) { // basic smoke tests that the runtime is alive and working runtime.Globals.SetVariable("hello", 42); - Assert.NotNull(runtime.GetEngine("py")); + Assert.That(runtime.GetEngine("py"), Is.Not.Null); if (options != null) { - Assert.AreEqual(runtime.Setup.DebugMode, true); - Assert.AreEqual(runtime.Setup.PrivateBinding, true); + Assert.That(true, Is.EqualTo(runtime.Setup.DebugMode)); + Assert.That(true, Is.EqualTo(runtime.Setup.PrivateBinding)); } - Assert.AreEqual(Python.GetSysModule(runtime).GetVariable("platform"), "cli"); - Assert.AreEqual(Python.GetBuiltinModule(runtime).GetVariable("True"), true); + Assert.That("cli", Is.EqualTo(Python.GetSysModule(runtime).GetVariable("platform"))); + Assert.That(true, Is.EqualTo(Python.GetBuiltinModule(runtime).GetVariable("True"))); if (System.Environment.OSVersion.Platform == System.PlatformID.Unix) { - Assert.AreEqual(Python.ImportModule(runtime, "posix").GetVariable("F_OK"), 0); + Assert.That(0, Is.EqualTo(Python.ImportModule(runtime, "posix").GetVariable("F_OK"))); } else { - Assert.AreEqual(Python.ImportModule(runtime, "nt").GetVariable("F_OK"), 0); + Assert.That(0, Is.EqualTo(Python.ImportModule(runtime, "nt").GetVariable("F_OK"))); } Assert.Throws(() => { @@ -388,14 +388,14 @@ public void ScenarioDynamicObjectAsScope() { var source = engine.CreateScriptSourceFromString("x = 42", SourceCodeKind.File); source.Compile().Execute(scope); - Assert.AreEqual(myScope._members.ContainsKey("__doc__"), true); - Assert.AreEqual(myScope._members.ContainsKey("x"), true); - Assert.AreEqual(myScope._members.ContainsKey("__file__"), true); + Assert.That(true, Is.EqualTo(myScope._members.ContainsKey("__doc__"))); + Assert.That(true, Is.EqualTo(myScope._members.ContainsKey("x"))); + Assert.That(true, Is.EqualTo(myScope._members.ContainsKey("__file__"))); source = engine.CreateScriptSourceFromString("'hello world'", SourceCodeKind.File); source.Compile().Execute(scope); - Assert.AreEqual(myScope._members["__doc__"], "hello world"); + Assert.That("hello world", Is.EqualTo(myScope._members["__doc__"])); } // tests where __doc__ gets assigned into a field/property @@ -406,13 +406,13 @@ public void ScenarioDynamicObjectAsScope() { var source = engine.CreateScriptSourceFromString("'hello world'\nx=42\n", SourceCodeKind.File); source.Compile().Execute(scope); - Assert.AreEqual(((ScopeDynamicObject4)myScope).__doc__, "hello world"); + Assert.That("hello world", Is.EqualTo(((ScopeDynamicObject4)myScope).__doc__)); myScope = new ScopeDynamicObject5(); scope = engine.CreateScope(myScope); source.Compile().Execute(scope); - Assert.AreEqual(((ScopeDynamicObject5)myScope).__doc__, "hello world"); + Assert.That("hello world", Is.EqualTo(((ScopeDynamicObject5)myScope).__doc__)); } } @@ -435,7 +435,7 @@ public void ScenarioCodePlex20472() { // Opening the file with explicitly specifying the correct encoding should work CompiledCode prog = _pe.CreateScriptSourceFromFile(fileName, Encoding.GetEncoding(1251)).Compile(); prog.Execute(); - Assert.AreEqual(prog.DefaultScope.GetVariable("s"), "\u041F\u0436\u0451"); + Assert.That(prog.DefaultScope.GetVariable("s"), Is.EqualTo("\u041F\u0436\u0451")); } [Test] @@ -449,7 +449,7 @@ public void ScenarioInterpreterNestedVariables() { ); var vars = CompilerHelpers.LightCompile(argBody)(42); - Assert.AreEqual(vars[0], 42); + Assert.That(42, Is.EqualTo(vars[0])); ParameterExpression tmp = Expression.Parameter(typeof(object), "tmp"); var body = Expression.Lambda>( @@ -465,8 +465,8 @@ public void ScenarioInterpreterNestedVariables() { ) ); - Assert.AreEqual(body.Compile()(), ClrModule.IsNetCoreApp || ClrModule.IsMono ? (object)42 : null); // https://github.com/IronLanguages/ironpython3/issues/908 - Assert.AreEqual(CompilerHelpers.LightCompile(body)(), null); + Assert.That(ClrModule.IsNetCoreApp || ClrModule.IsMono ? (object)42 : null, Is.EqualTo(body.Compile()())); // https://github.com/IronLanguages/ironpython3/issues/908 + Assert.That(null, Is.EqualTo(CompilerHelpers.LightCompile(body)())); body = Expression.Lambda>( Expression.Block( @@ -482,8 +482,8 @@ public void ScenarioInterpreterNestedVariables() { ) ) ); - Assert.AreEqual(CompilerHelpers.LightCompile(body)(), null); - Assert.AreEqual(body.Compile()(), null); + Assert.That(null, Is.EqualTo(CompilerHelpers.LightCompile(body)())); + Assert.That(null, Is.EqualTo(body.Compile()())); } public class TestCodePlex23562 { @@ -506,7 +506,7 @@ public void ScenarioCodePlex23562() { _pe.Execute(pyCode, scope); TestCodePlex23562 temp = scope.GetVariable("test"); - Assert.True(temp.MethodCalled); + Assert.That(temp.MethodCalled); } [Test] @@ -524,12 +524,12 @@ global py_func_called _pe.Execute(pyCode, scope); IList str_tuple = scope.GetVariable>("str_tuple"); - Assert.AreEqual(str_tuple.Count, 2); + Assert.That(2, Is.EqualTo(str_tuple.Count)); IList str_list = scope.GetVariable>("str_list"); - Assert.AreEqual(str_list.Count, 3); + Assert.That(3, Is.EqualTo(str_list.Count)); VoidDelegate py_func = scope.GetVariable("py_func"); py_func(); - Assert.AreEqual(scope.GetVariable("py_func_called"), true); + Assert.That(true, Is.EqualTo(scope.GetVariable("py_func_called"))); } [Test] @@ -547,7 +547,7 @@ def __init__(self, a, b, c): object KKlass = scope.GetVariable("K"); object[] Kparams = new object[] { 1, 3.14, "abc" }; _pe.Operations.CreateInstance(KKlass, Kparams); - Assert.AreEqual(scope.GetVariable("A"), 1); + Assert.That(1, Is.EqualTo(scope.GetVariable("A"))); } // Execute @@ -562,12 +562,12 @@ public void ScenarioExecute() { // field: assign and get back _pe.Execute("clsPart.Field = 100", scope); _pe.Execute("if 100 != clsPart.Field: raise AssertionError('test failed')", scope); - Assert.AreEqual(100, clsPart.Field); + Assert.That(clsPart.Field, Is.EqualTo(100)); // property: assign and get back _pe.Execute("clsPart.Property = clsPart.Field", scope); _pe.Execute("if 100 != clsPart.Property: raise AssertionError('test failed')", scope); - Assert.AreEqual(100, clsPart.Property); + Assert.That(clsPart.Property, Is.EqualTo(100)); // method: Event not set yet _pe.Execute("a = clsPart.Method(2)", scope); @@ -596,7 +596,7 @@ public void ScenarioExecute() { // reset the same variable with integer scope.SetVariable(clspartName, 1); _pe.Execute("if 1 != clsPart: raise AssertionError('test failed')", scope); - Assert.AreEqual((int)(object)scope.GetVariable(clspartName), 1); + Assert.That(1, Is.EqualTo((int)(object)scope.GetVariable(clspartName))); ScriptSource su = _pe.CreateScriptSourceFromString(""); Assert.Throws(() => { @@ -609,8 +609,8 @@ public static void ScenarioTryGetMember() { var engine = Python.CreateEngine(); var str = ClrModule.GetPythonType(typeof(string)); object result; - Assert.AreEqual(engine.Operations.TryGetMember(str, "Equals", out result), true); - Assert.AreEqual(result.ToString(), "IronPython.Runtime.Types.BuiltinFunction"); + Assert.That(true, Is.EqualTo(engine.Operations.TryGetMember(str, "Equals", out result))); + Assert.That("IronPython.Runtime.Types.BuiltinFunction", Is.EqualTo(result.ToString())); } [Test] @@ -640,7 +640,7 @@ public static void ScenarioInterfaceExtensions() { ScriptSource src = engine.CreateScriptSourceFromString("x.Bar()"); ScriptScope scope = engine.CreateScope(); scope.SetVariable("x", new Fooable()); - Assert.AreEqual((object)src.Execute(scope), "Bar Called"); + Assert.That("Bar Called", Is.EqualTo((object)src.Execute(scope))); } private class MyInvokeMemberBinder : InvokeMemberBinder { @@ -939,20 +939,20 @@ class EmptyNC(object): pass foreach (var test in tests) { var result = new List(doc.GetOverloads(test.Obj)); - Assert.AreEqual(result.Count, test.Result.Length); + Assert.That(test.Result.Length, Is.EqualTo(result.Count)); for (int i = 0; i < result.Count; i++) { var received = result[i]; ; var expected = test.Result[i]; - Assert.AreEqual(received.Parameters.Count, expected.Length); + Assert.That(expected.Length, Is.EqualTo(received.Parameters.Count)); var recvParams = new List(received.Parameters); for (int j = 0; j < expected.Length; j++) { var receivedParam = recvParams[j]; var expectedParam = expected[j]; - Assert.AreEqual(receivedParam.Flags, expectedParam.ParamAttrs); - Assert.AreEqual(receivedParam.Name, expectedParam.ParamName); + Assert.That(expectedParam.ParamAttrs, Is.EqualTo(receivedParam.Flags)); + Assert.That(expectedParam.ParamName, Is.EqualTo(receivedParam.Name)); } } } @@ -996,7 +996,7 @@ class EmptyNC(object): pass private void ContainsMemberName(ICollection members, string name, MemberKind kind) { foreach (var member in members) { if (member.Name == name) { - Assert.AreEqual(member.Kind, kind); + Assert.That(kind, Is.EqualTo(member.Kind)); return; } } @@ -1284,74 +1284,74 @@ def Invokable(*args, **kwargs): // if it lives on a system type we should do a fallback invoke member var site = CallSite>.Create(new MyInvokeMemberBinder("Count", new CallInfo(0))); - Assert.AreEqual(site.Target(site, (object)scope.GetVariable("alinst")), "FallbackInvokeMember"); + Assert.That("FallbackInvokeMember", Is.EqualTo(site.Target(site, (object)scope.GetVariable("alinst")))); // invoke a function that's a member on an object foreach (object inst in allObjects) { site = CallSite>.Create(new MyInvokeMemberBinder("TestFunc", new CallInfo(0))); - Assert.AreEqual(site.Target(site, inst), "TestFunc"); + Assert.That("TestFunc", Is.EqualTo(site.Target(site, inst))); } // invoke a field / property that's on an object foreach (object inst in allObjects) { site = CallSite>.Create(new MyInvokeMemberBinder("InstVal", new CallInfo(0))); - Assert.AreEqual(site.Target(site, inst), "FallbackInvokeInstVal"); + Assert.That("FallbackInvokeInstVal", Is.EqualTo(site.Target(site, inst))); site = CallSite>.Create(new MyInvokeMemberBinder("ClassVal", new CallInfo(0))); - Assert.AreEqual(site.Target(site, inst), "FallbackInvokeClassVal"); + Assert.That("FallbackInvokeClassVal", Is.EqualTo(site.Target(site, inst))); if (!(inst is PythonFunction)) { site = CallSite>.Create(new MyInvokeMemberBinder("SomeMethodThatNeverExists", new CallInfo(0))); - Assert.AreEqual(site.Target(site, inst), "FallbackInvokeMember"); + Assert.That("FallbackInvokeMember", Is.EqualTo(site.Target(site, inst))); } } // invoke a field / property that's not defined on objects w/ __getattr__ foreach (object inst in getattrObjects) { site = CallSite>.Create(new MyInvokeMemberBinder("DoesNotExist", new CallInfo(0))); - Assert.AreEqual(site.Target(site, inst), "FallbackInvokeDoesNotExist"); + Assert.That("FallbackInvokeDoesNotExist", Is.EqualTo(site.Target(site, inst))); } // invoke a field / property that's not defined on objects w/ __getattribute__ foreach (object inst in getattributeObjects) { site = CallSite>.Create(new MyInvokeMemberBinder("DoesNotExist", new CallInfo(0))); - Assert.AreEqual(site.Target(site, inst), "FallbackInvokeDoesNotExist"); + Assert.That("FallbackInvokeDoesNotExist", Is.EqualTo(site.Target(site, inst))); site = CallSite>.Create(new MyInvokeMemberBinder("Count", new CallInfo(0))); - Assert.AreEqual(site.Target(site, inst), "FallbackInvokeCount"); + Assert.That("FallbackInvokeCount", Is.EqualTo(site.Target(site, inst))); site = CallSite>.Create(new MyInvokeMemberBinder("TestFunc", new CallInfo(0))); - Assert.AreEqual(site.Target(site, inst), "FallbackInvokeTestFunc"); + Assert.That("FallbackInvokeTestFunc", Is.EqualTo(site.Target(site, inst))); site = CallSite>.Create(new MyInvokeMemberBinder("InstVal", new CallInfo(0))); - Assert.AreEqual(site.Target(site, inst), "FallbackInvokeInstVal"); + Assert.That("FallbackInvokeInstVal", Is.EqualTo(site.Target(site, inst))); site = CallSite>.Create(new MyInvokeMemberBinder("ClassVal", new CallInfo(0))); - Assert.AreEqual(site.Target(site, inst), "FallbackInvokeClassVal"); + Assert.That("FallbackInvokeClassVal", Is.EqualTo(site.Target(site, inst))); } foreach (object inst in indexableObjects) { var site2 = CallSite>.Create(new MyGetIndexBinder(new CallInfo(1))); - Assert.AreEqual(site2.Target(site2, inst, "index"), "index"); + Assert.That("index", Is.EqualTo(site2.Target(site2, inst, "index"))); var site3 = CallSite>.Create(new MySetIndexBinder(new CallInfo(1))); - Assert.AreEqual(site3.Target(site3, inst, "index", "value"), "value"); + Assert.That("value", Is.EqualTo(site3.Target(site3, inst, "index", "value"))); site = CallSite>.Create(new MyGetMemberBinder("LastSetItem")); IList res = (IList)site.Target(site, inst); - Assert.AreEqual(res.Count, 2); - Assert.AreEqual(res[0], "index"); - Assert.AreEqual(res[1], "value"); + Assert.That(2, Is.EqualTo(res.Count)); + Assert.That("index", Is.EqualTo(res[0])); + Assert.That("value", Is.EqualTo(res[1])); } foreach (object inst in unindexableObjects) { var site2 = CallSite>.Create(new MyGetIndexBinder(new CallInfo(1))); //Console.WriteLine(inst); - Assert.AreEqual(site2.Target(site2, inst, "index"), "FallbackGetIndexindex"); + Assert.That("FallbackGetIndexindex", Is.EqualTo(site2.Target(site2, inst, "index"))); var site3 = CallSite>.Create(new MySetIndexBinder(new CallInfo(1))); - Assert.AreEqual(site3.Target(site3, inst, "index", "value"), "FallbackSetIndexindexvalue"); + Assert.That("FallbackSetIndexindexvalue", Is.EqualTo(site3.Target(site3, inst, "index", "value"))); } foreach (object inst in invokableObjects) { @@ -1374,7 +1374,7 @@ def Invokable(*args, **kwargs): foreach (object inst in convertableObjects) { // These may be invalid according to the DLR (wrong ret type) but currently work today. site = CallSite>.Create(new MyConvertBinder(typeof(string))); - Assert.AreEqual(site.Target(site, inst), "Python"); + Assert.That("Python", Is.EqualTo(site.Target(site, inst))); var dlgsiteo = CallSite>.Create(new MyConvertBinder(typeof(Func), null)); VerifyFunction(new[] { "foo" }, Array.Empty(), ((Func)(dlgsiteo.Target(dlgsiteo, inst)))("foo")); @@ -1384,24 +1384,24 @@ def Invokable(*args, **kwargs): // strongly typed return versions var ssite = CallSite>.Create(new MyConvertBinder(typeof(string))); - Assert.AreEqual(ssite.Target(ssite, inst), "Python"); + Assert.That("Python", Is.EqualTo(ssite.Target(ssite, inst))); // this call site works only if __int__ happens to return an Int32 instance or a BigInteger instance that fits in 32 bits var isite = CallSite>.Create(new MyConvertBinder(typeof(int), 23)); - Assert.AreEqual(isite.Target(isite, inst), 42); + Assert.That(42, Is.EqualTo(isite.Target(isite, inst))); var dsite = CallSite>.Create(new MyConvertBinder(typeof(double), 23.0)); - Assert.AreEqual(dsite.Target(dsite, inst), 42.0); + Assert.That(42.0, Is.EqualTo(dsite.Target(dsite, inst))); var csite = CallSite>.Create(new MyConvertBinder(typeof(Complex), new Complex(0, 23))); - Assert.AreEqual(csite.Target(csite, inst), new Complex(0, 42)); + Assert.That(new Complex(0, 42), Is.EqualTo(csite.Target(csite, inst))); var bsite = CallSite>.Create(new MyConvertBinder(typeof(bool), true)); - Assert.AreEqual(bsite.Target(bsite, inst), false); + Assert.That(false, Is.EqualTo(bsite.Target(bsite, inst))); // this call site works regardless whether __int__ returns a BigInteger or Int32 instance var bisite = CallSite>.Create(new MyConvertBinder(typeof(BigInteger), (BigInteger)23)); - Assert.AreEqual(bisite.Target(bisite, inst), (BigInteger)42); + Assert.That((BigInteger)42, Is.EqualTo(bisite.Target(bisite, inst))); var dlgsite = CallSite>>.Create(new MyConvertBinder(typeof(Func), null)); VerifyFunction(new[] { "foo" }, Array.Empty(), dlgsite.Target(dlgsite, inst)("foo")); @@ -1413,26 +1413,26 @@ def Invokable(*args, **kwargs): foreach (object inst in unconvertableObjects) { // These may be invalid according to the DLR (wrong ret type) but currently work today. site = CallSite>.Create(new MyConvertBinder(typeof(string))); - Assert.AreEqual(site.Target(site, inst), "Converted"); + Assert.That("Converted", Is.EqualTo(site.Target(site, inst))); // strongly typed return versions var ssite = CallSite>.Create(new MyConvertBinder(typeof(string))); - Assert.AreEqual(ssite.Target(ssite, inst), "Converted"); + Assert.That("Converted", Is.EqualTo(ssite.Target(ssite, inst))); var isite = CallSite>.Create(new MyConvertBinder(typeof(int), 23)); - Assert.AreEqual(isite.Target(isite, inst), 23); + Assert.That(23, Is.EqualTo(isite.Target(isite, inst))); var dsite = CallSite>.Create(new MyConvertBinder(typeof(double), 23.0)); - Assert.AreEqual(dsite.Target(dsite, inst), 23.0); + Assert.That(23.0, Is.EqualTo(dsite.Target(dsite, inst))); var csite = CallSite>.Create(new MyConvertBinder(typeof(Complex), new Complex(0, 23.0))); - Assert.AreEqual(csite.Target(csite, inst), new Complex(0, 23.0)); + Assert.That(new Complex(0, 23.0), Is.EqualTo(csite.Target(csite, inst))); var bsite = CallSite>.Create(new MyConvertBinder(typeof(bool), true)); - Assert.AreEqual(bsite.Target(bsite, inst), true); + Assert.That(true, Is.EqualTo(bsite.Target(bsite, inst))); var bisite = CallSite>.Create(new MyConvertBinder(typeof(BigInteger), (BigInteger)23)); - Assert.AreEqual(bisite.Target(bisite, inst), (BigInteger)23); + Assert.That((BigInteger)23, Is.EqualTo(bisite.Target(bisite, inst))); } // get on .NET member should fallback @@ -1440,84 +1440,84 @@ def Invokable(*args, **kwargs): if (!ClrModule.IsMono && !ClrModule.IsNetCoreApp) { // property site = CallSite>.Create(new MyGetMemberBinder("AllowDrop")); - Assert.AreEqual(site.Target(site, (object)scope.GetVariable("controlinst")), "FallbackGetMember"); + Assert.That("FallbackGetMember", Is.EqualTo(site.Target(site, (object)scope.GetVariable("controlinst")))); // method site = CallSite>.Create(new MyGetMemberBinder("BringToFront")); - Assert.AreEqual(site.Target(site, (object)scope.GetVariable("controlinst")), "FallbackGetMember"); + Assert.That("FallbackGetMember", Is.EqualTo(site.Target(site, (object)scope.GetVariable("controlinst")))); // protected method site = CallSite>.Create(new MyGetMemberBinder("OnParentChanged")); - Assert.AreEqual(site.Target(site, (object)scope.GetVariable("controlinst")), "FallbackGetMember"); + Assert.That("FallbackGetMember", Is.EqualTo(site.Target(site, (object)scope.GetVariable("controlinst")))); // event site = CallSite>.Create(new MyGetMemberBinder("DoubleClick")); - Assert.AreEqual(site.Target(site, (object)scope.GetVariable("controlinst")), "FallbackGetMember"); + Assert.That("FallbackGetMember", Is.EqualTo(site.Target(site, (object)scope.GetVariable("controlinst")))); } site = CallSite>.Create(new MyInvokeMemberBinder("something", new CallInfo(0))); - Assert.AreEqual(site.Target(site, (object)scope.GetVariable("ns_getattrinst")), "FallbackInvokegetattrsomething"); + Assert.That("FallbackInvokegetattrsomething", Is.EqualTo(site.Target(site, (object)scope.GetVariable("ns_getattrinst")))); foreach (object inst in iterableObjects) { // converting a type which implements __iter__ var enumsite = CallSite>.Create(new MyConvertBinder(typeof(IEnumerable))); IEnumerable ie = enumsite.Target(enumsite, inst); IEnumerator ator = ie.GetEnumerator(); - Assert.AreEqual(ator.MoveNext(), true); - Assert.AreEqual(ator.Current, 1); - Assert.AreEqual(ator.MoveNext(), true); - Assert.AreEqual(ator.Current, 2); - Assert.AreEqual(ator.MoveNext(), true); - Assert.AreEqual(ator.Current, 3); - Assert.AreEqual(ator.MoveNext(), false); + Assert.That(true, Is.EqualTo(ator.MoveNext())); + Assert.That(1, Is.EqualTo(ator.Current)); + Assert.That(true, Is.EqualTo(ator.MoveNext())); + Assert.That(2, Is.EqualTo(ator.Current)); + Assert.That(true, Is.EqualTo(ator.MoveNext())); + Assert.That(3, Is.EqualTo(ator.Current)); + Assert.That(false, Is.EqualTo(ator.MoveNext())); var enumobjsite = CallSite>.Create(new MyConvertBinder(typeof(IEnumerable))); ie = (IEnumerable)enumobjsite.Target(enumobjsite, inst); ator = ie.GetEnumerator(); - Assert.AreEqual(ator.MoveNext(), true); - Assert.AreEqual(ator.Current, 1); - Assert.AreEqual(ator.MoveNext(), true); - Assert.AreEqual(ator.Current, 2); - Assert.AreEqual(ator.MoveNext(), true); - Assert.AreEqual(ator.Current, 3); - Assert.AreEqual(ator.MoveNext(), false); + Assert.That(true, Is.EqualTo(ator.MoveNext())); + Assert.That(1, Is.EqualTo(ator.Current)); + Assert.That(true, Is.EqualTo(ator.MoveNext())); + Assert.That(2, Is.EqualTo(ator.Current)); + Assert.That(true, Is.EqualTo(ator.MoveNext())); + Assert.That(3, Is.EqualTo(ator.Current)); + Assert.That(false, Is.EqualTo(ator.MoveNext())); var enumatorsite = CallSite>.Create(new MyConvertBinder(typeof(IEnumerator))); ator = enumatorsite.Target(enumatorsite, inst); - Assert.AreEqual(ator.MoveNext(), true); - Assert.AreEqual(ator.Current, 1); - Assert.AreEqual(ator.MoveNext(), true); - Assert.AreEqual(ator.Current, 2); - Assert.AreEqual(ator.MoveNext(), true); - Assert.AreEqual(ator.Current, 3); - Assert.AreEqual(ator.MoveNext(), false); + Assert.That(true, Is.EqualTo(ator.MoveNext())); + Assert.That(1, Is.EqualTo(ator.Current)); + Assert.That(true, Is.EqualTo(ator.MoveNext())); + Assert.That(2, Is.EqualTo(ator.Current)); + Assert.That(true, Is.EqualTo(ator.MoveNext())); + Assert.That(3, Is.EqualTo(ator.Current)); + Assert.That(false, Is.EqualTo(ator.MoveNext())); var enumatorobjsite = CallSite>.Create(new MyConvertBinder(typeof(IEnumerator))); ator = (IEnumerator)enumatorobjsite.Target(enumatorobjsite, inst); - Assert.AreEqual(ator.MoveNext(), true); - Assert.AreEqual(ator.Current, 1); - Assert.AreEqual(ator.MoveNext(), true); - Assert.AreEqual(ator.Current, 2); - Assert.AreEqual(ator.MoveNext(), true); - Assert.AreEqual(ator.Current, 3); - Assert.AreEqual(ator.MoveNext(), false); + Assert.That(true, Is.EqualTo(ator.MoveNext())); + Assert.That(1, Is.EqualTo(ator.Current)); + Assert.That(true, Is.EqualTo(ator.MoveNext())); + Assert.That(2, Is.EqualTo(ator.Current)); + Assert.That(true, Is.EqualTo(ator.MoveNext())); + Assert.That(3, Is.EqualTo(ator.Current)); + Assert.That(false, Is.EqualTo(ator.MoveNext())); } site = CallSite>.Create(new MyUnaryBinder(ExpressionType.Not)); - Assert.AreEqual(site.Target(site, (object)scope.GetVariable("nsinst")), true); - Assert.AreEqual(site.Target(site, (object)scope.GetVariable("ns_nonzero_inst")), false); - Assert.AreEqual(site.Target(site, (object)scope.GetVariable("ns_len0_inst")), true); - Assert.AreEqual(site.Target(site, (object)scope.GetVariable("ns_len1_inst")), false); + Assert.That(true, Is.EqualTo(site.Target(site, (object)scope.GetVariable("nsinst")))); + Assert.That(false, Is.EqualTo(site.Target(site, (object)scope.GetVariable("ns_nonzero_inst")))); + Assert.That(true, Is.EqualTo(site.Target(site, (object)scope.GetVariable("ns_len0_inst")))); + Assert.That(false, Is.EqualTo(site.Target(site, (object)scope.GetVariable("ns_len1_inst")))); site = CallSite>.Create(new MyInvokeMemberBinder("ToString", new CallInfo(0))); - Assert.AreEqual(site.Target(site, (object)scope.GetVariable("range")), "FallbackInvokeMember"); + Assert.That("FallbackInvokeMember", Is.EqualTo(site.Target(site, (object)scope.GetVariable("range")))); // invoke a function defined as a member of a function site = CallSite>.Create(new MyInvokeMemberBinder("SubFunc", new CallInfo(0))); - Assert.AreEqual(site.Target(site, (object)scope.GetVariable("TestFunc")), "TestFunc"); + Assert.That("TestFunc", Is.EqualTo(site.Target(site, (object)scope.GetVariable("TestFunc")))); site = CallSite>.Create(new MyInvokeMemberBinder("DoesNotExist", new CallInfo(0))); - Assert.AreEqual(site.Target(site, (object)scope.GetVariable("TestFunc")), "FallbackInvokeMember"); + Assert.That("FallbackInvokeMember", Is.EqualTo(site.Target(site, (object)scope.GetVariable("TestFunc")))); } private class MyDynamicObject : DynamicObject { @@ -1626,7 +1626,7 @@ public void ScenarioDlrInterop_ConsumeDynamicObject() { }; foreach (var test in tests) { - Assert.AreEqual(test.Result, (object)_pe.Execute(test.TestCase, scope)); + Assert.That((object)_pe.Execute(test.TestCase, scope), Is.EqualTo(test.Result)); } var tests2 = new[] { @@ -1638,22 +1638,22 @@ public void ScenarioDlrInterop_ConsumeDynamicObject() { foreach (var test in tests2) { _pe.Execute(test.TestCase, scope); - Assert.AreEqual(test.Last, dynObj.Last); + Assert.That(dynObj.Last, Is.EqualTo(test.Last)); } } private void VerifyFunction(object[] results, string[] names, object value) { IList res = (IList)value; - Assert.AreEqual(res.Count, 2); + Assert.That(2, Is.EqualTo(res.Count)); IList positional = (IList)res[0]; IDictionary kwargs = (IDictionary)res[1]; for (int i = 0; i < positional.Count; i++) { - Assert.AreEqual(positional[i], results[i]); + Assert.That(results[i], Is.EqualTo(positional[i])); } for (int i = positional.Count; i < results.Length; i++) { - Assert.AreEqual(kwargs[names[i - positional.Count]], results[i]); + Assert.That(results[i], Is.EqualTo(kwargs[names[i - positional.Count]])); } } @@ -1669,24 +1669,24 @@ public void ScenarioEvaluateInAnonymousEngineModule() { scope3.SetVariable("x", 2); - Assert.AreEqual(0, _pe.Execute("x", scope1)); - Assert.AreEqual(0, (int)(object)scope1.GetVariable("x")); + Assert.That(_pe.Execute("x", scope1), Is.EqualTo(0)); + Assert.That((int)(object)scope1.GetVariable("x"), Is.EqualTo(0)); - Assert.AreEqual(1, _pe.Execute("x", scope2)); - Assert.AreEqual(1, (int)(object)scope2.GetVariable("x")); + Assert.That(_pe.Execute("x", scope2), Is.EqualTo(1)); + Assert.That((int)(object)scope2.GetVariable("x"), Is.EqualTo(1)); - Assert.AreEqual(2, _pe.Execute("x", scope3)); - Assert.AreEqual(2, (int)(object)scope3.GetVariable("x")); + Assert.That(_pe.Execute("x", scope3), Is.EqualTo(2)); + Assert.That((int)(object)scope3.GetVariable("x"), Is.EqualTo(2)); } [Test] public void ScenarioObjectOperations() { var ops = _pe.Operations; - Assert.AreEqual("(1, 2, 3)", ops.Format(new PythonTuple(new object[] { 1, 2, 3 }))); + Assert.That(ops.Format(new PythonTuple(new object[] { 1, 2, 3 })), Is.EqualTo("(1, 2, 3)")); var scope = _pe.CreateScope(); scope.SetVariable("ops", ops); - Assert.AreEqual("[1, 2, 3]", _pe.Execute("ops.Format([1,2,3])", scope)); + Assert.That(_pe.Execute("ops.Format([1,2,3])", scope), Is.EqualTo("[1, 2, 3]")); ScriptSource src = _pe.CreateScriptSourceFromString("def f(*args): return args", SourceCodeKind.Statements); src.Execute(scope); @@ -1698,7 +1698,7 @@ public void ScenarioObjectOperations() { inp[j] = j; } - Assert.AreEqual((object)ops.Invoke(f, inp), PythonTuple.MakeTuple(inp)); + Assert.That(PythonTuple.MakeTuple(inp), Is.EqualTo((object)ops.Invoke(f, inp))); } ScriptScope mod = _env.CreateScope(); @@ -1717,9 +1717,9 @@ def __init__(self, x, y): object foo = ops.CreateInstance(klass, 123, 444); - Assert.AreEqual(ops.GetMember(foo, "abc"), 3); - Assert.AreEqual(ops.GetMember(foo, "x"), 123); - Assert.AreEqual(ops.GetMember(foo, "y"), 444); + Assert.That(3, Is.EqualTo(ops.GetMember(foo, "abc"))); + Assert.That(123, Is.EqualTo(ops.GetMember(foo, "x"))); + Assert.That(444, Is.EqualTo(ops.GetMember(foo, "y"))); } [Test] @@ -1737,7 +1737,7 @@ public void ScenarioCP712() { public void ScenarioCP24784() { var code = _pe.CreateScriptSourceFromString("def f():\r\n \r\n print(1)", SourceCodeKind.InteractiveCode); - Assert.AreEqual(code.GetCodeProperties(), ScriptCodeParseResult.IncompleteStatement); + Assert.That(ScriptCodeParseResult.IncompleteStatement, Is.EqualTo(code.GetCodeProperties())); } public delegate int CP19724Delegate(double p1); @@ -1756,8 +1756,8 @@ global X src.Execute(scope1); CP19724Delegate tDelegate = scope1.GetVariable("k"); - Assert.AreEqual(7, tDelegate(3.14)); - Assert.AreEqual(42, scope1.GetVariable("X")); + Assert.That(tDelegate(3.14), Is.EqualTo(7)); + Assert.That(scope1.GetVariable("X"), Is.EqualTo(42)); } [Test] @@ -1775,17 +1775,17 @@ public void ScenarioEvaluateInPublishedEngineModule() { // Ensure that the default EngineModule is not affected x = pc.CreateSnippet("x", SourceCodeKind.Expression).Execute(otherModule.Scope); - Assert.AreEqual(0, (int)x); + Assert.That((int)x, Is.EqualTo(0)); // Ensure that the published context has been updated as expected x = pc.CreateSnippet("x", SourceCodeKind.Expression).Execute(publishedModule.Scope); - Assert.AreEqual(1, (int)x); + Assert.That((int)x, Is.EqualTo(1)); // Ensure that the published context is accessible from other contexts using sys.modules // TODO: do better: // pe.Import("sys", ScriptDomainManager.CurrentManager.DefaultModule); pc.CreateSnippet("from published_context_test import x", SourceCodeKind.Statements).Execute(otherModule.Scope); x = pc.CreateSnippet("x", SourceCodeKind.Expression).Execute(otherModule.Scope); - Assert.AreEqual(1, (int)x); + Assert.That((int)x, Is.EqualTo(1)); } private class CustomDictionary : IDictionary { @@ -1909,19 +1909,19 @@ public void ScenarioCustomDictionary() { ScriptScope customModule = _pe.Runtime.CreateScope(new ObjectDictionaryExpando(customGlobals)); // Evaluate - Assert.AreEqual(_pe.Execute("customSymbol + 1", customModule), CustomDictionary.customSymbolValue + 1); + Assert.That(CustomDictionary.customSymbolValue + 1, Is.EqualTo(_pe.Execute("customSymbol + 1", customModule))); // Execute _pe.Execute("customSymbolPlusOne = customSymbol + 1", customModule); - Assert.AreEqual(_pe.Execute("customSymbolPlusOne", customModule), CustomDictionary.customSymbolValue + 1); - Assert.AreEqual(customModule.GetVariable("customSymbolPlusOne"), CustomDictionary.customSymbolValue + 1); + Assert.That(CustomDictionary.customSymbolValue + 1, Is.EqualTo(_pe.Execute("customSymbolPlusOne", customModule))); + Assert.That(CustomDictionary.customSymbolValue + 1, Is.EqualTo(customModule.GetVariable("customSymbolPlusOne"))); // Compile CompiledCode compiledCode = _pe.CreateScriptSourceFromString("customSymbolPlusTwo = customSymbol + 2").Compile(); compiledCode.Execute(customModule); - Assert.AreEqual(_pe.Execute("customSymbolPlusTwo", customModule), CustomDictionary.customSymbolValue + 2); - Assert.AreEqual(customModule.GetVariable("customSymbolPlusTwo"), CustomDictionary.customSymbolValue + 2); + Assert.That(CustomDictionary.customSymbolValue + 2, Is.EqualTo(_pe.Execute("customSymbolPlusTwo", customModule))); + Assert.That(CustomDictionary.customSymbolValue + 2, Is.EqualTo(customModule.GetVariable("customSymbolPlusTwo"))); // check overriding of Add try { @@ -1949,7 +1949,7 @@ public void ScenarioCustomDictionary() { // vars() IDictionary vars = _pe.Execute("vars()", customModule); - Assert.AreEqual(true, vars.Contains("customSymbol")); + Assert.That(vars.Contains("customSymbol"), Is.EqualTo(true)); // Miscellaneous APIs //IntIntDelegate d = pe.CreateLambda("customSymbol + arg", customModule); @@ -1973,8 +1973,8 @@ def __call__(self, arg): b = Y()", SourceCodeKind.Statements).Execute(scope); var a = scope.GetVariable>("a"); var b = scope.GetVariable>("b"); - Assert.AreEqual(a(42), 42); - Assert.AreEqual(b(42), 42); + Assert.That(42, Is.EqualTo(a(42))); + Assert.That(42, Is.EqualTo(b(42))); } // Evaluate @@ -1982,43 +1982,43 @@ def __call__(self, arg): public void ScenarioEvaluate() { ScriptScope scope = _env.CreateScope(); - Assert.AreEqual(10, _pe.CreateScriptSourceFromString("4+6").Execute(scope)); - Assert.AreEqual(null, (object)_pe.CreateScriptSourceFromString("if True: pass").Execute(scope)); + Assert.That(_pe.CreateScriptSourceFromString("4+6").Execute(scope), Is.EqualTo(10)); + Assert.That((object)_pe.CreateScriptSourceFromString("if True: pass").Execute(scope), Is.EqualTo(null)); - Assert.AreEqual(10, _pe.CreateScriptSourceFromString("4+6", SourceCodeKind.AutoDetect).Execute(scope)); - Assert.AreEqual(null, (object)_pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.AutoDetect).Execute(scope)); + Assert.That(_pe.CreateScriptSourceFromString("4+6", SourceCodeKind.AutoDetect).Execute(scope), Is.EqualTo(10)); + Assert.That((object)_pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.AutoDetect).Execute(scope), Is.EqualTo(null)); - Assert.AreEqual(10, _pe.CreateScriptSourceFromString("4+6", SourceCodeKind.Expression).Execute(scope)); + Assert.That(_pe.CreateScriptSourceFromString("4+6", SourceCodeKind.Expression).Execute(scope), Is.EqualTo(10)); Assert.Throws(() => _pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.Expression).Execute(scope)); - Assert.AreEqual(null, (object)_pe.CreateScriptSourceFromString("4+6", SourceCodeKind.File).Execute(scope)); - Assert.AreEqual(null, (object)_pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.File).Execute(scope)); + Assert.That((object)_pe.CreateScriptSourceFromString("4+6", SourceCodeKind.File).Execute(scope), Is.EqualTo(null)); + Assert.That((object)_pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.File).Execute(scope), Is.EqualTo(null)); - Assert.AreEqual(null, (object)_pe.CreateScriptSourceFromString("4+6", SourceCodeKind.SingleStatement).Execute(scope)); - Assert.AreEqual(null, (object)_pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.SingleStatement).Execute(scope)); + Assert.That((object)_pe.CreateScriptSourceFromString("4+6", SourceCodeKind.SingleStatement).Execute(scope), Is.EqualTo(null)); + Assert.That((object)_pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.SingleStatement).Execute(scope), Is.EqualTo(null)); - Assert.AreEqual(null, (object)_pe.CreateScriptSourceFromString("4+6", SourceCodeKind.Statements).Execute(scope)); - Assert.AreEqual(null, (object)_pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.Statements).Execute(scope)); + Assert.That((object)_pe.CreateScriptSourceFromString("4+6", SourceCodeKind.Statements).Execute(scope), Is.EqualTo(null)); + Assert.That((object)_pe.CreateScriptSourceFromString("if True: pass", SourceCodeKind.Statements).Execute(scope), Is.EqualTo(null)); - Assert.AreEqual(10, (int)(object)_pe.Execute("4+6", scope)); - Assert.AreEqual(10, _pe.Execute("4+6", scope)); + Assert.That((int)(object)_pe.Execute("4+6", scope), Is.EqualTo(10)); + Assert.That(_pe.Execute("4+6", scope), Is.EqualTo(10)); - Assert.AreEqual("abab", (string)(object)_pe.Execute("'ab' * 2", scope)); - Assert.AreEqual("abab", _pe.Execute("'ab' * 2", scope)); + Assert.That((string)(object)_pe.Execute("'ab' * 2", scope), Is.EqualTo("abab")); + Assert.That(_pe.Execute("'ab' * 2", scope), Is.EqualTo("abab")); ClsPart clsPart = new ClsPart(); scope.SetVariable(clspartName, clsPart); - Assert.AreEqual(clsPart, ((object)_pe.Execute("clsPart", scope)) as ClsPart); - Assert.AreEqual(clsPart, _pe.Execute("clsPart", scope)); + Assert.That(((object)_pe.Execute("clsPart", scope)) as ClsPart, Is.EqualTo(clsPart)); + Assert.That(_pe.Execute("clsPart", scope), Is.EqualTo(clsPart)); _pe.Execute("clsPart.Field = 100", scope); - Assert.AreEqual(100, (int)(object)_pe.Execute("clsPart.Field", scope)); - Assert.AreEqual(100, _pe.Execute("clsPart.Field", scope)); + Assert.That((int)(object)_pe.Execute("clsPart.Field", scope), Is.EqualTo(100)); + Assert.That(_pe.Execute("clsPart.Field", scope), Is.EqualTo(100)); // Ensure that we can get back a delegate to a Python method _pe.Execute("def IntIntMethod(a): return a * 100", scope); IntIntDelegate d = _pe.Execute("IntIntMethod", scope); - Assert.AreEqual(d(2), 2 * 100); + Assert.That(2 * 100, Is.EqualTo(d(2))); } [Test] @@ -2057,10 +2057,10 @@ def f(): pass ncinstnames.Sort(); fnames.Sort(); - Assert.AreEqual(ncnames.ToArray(), new[] { "__class__", "__delattr__", "__dict__", "__doc__", "__eq__", "__format__", "__ge__", "__getattribute__", "__gt__", "__hash__", "__init__", "__le__", "__lt__", "__module__", "__ne__", "__new__", "__reduce__", "__reduce_ex__", "__repr__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "__weakref__", "abc", "classmethod", "foo", "staticfunc" }); - Assert.AreEqual(ncinstnames.ToArray(), new[] { "__class__", "__delattr__", "__dict__", "__doc__", "__eq__", "__format__", "__ge__", "__getattribute__", "__gt__", "__hash__", "__init__", "__le__", "__lt__", "__module__", "__ne__", "__new__", "__reduce__", "__reduce_ex__", "__repr__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "__weakref__", "abc", "baz", "classmethod", "foo", "staticfunc" }); + Assert.That(new[] { "__class__", "__delattr__", "__dict__", "__doc__", "__eq__", "__format__", "__ge__", "__getattribute__", "__gt__", "__hash__", "__init__", "__le__", "__lt__", "__module__", "__ne__", "__new__", "__reduce__", "__reduce_ex__", "__repr__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "__weakref__", "abc", "classmethod", "foo", "staticfunc" }, Is.EqualTo(ncnames.ToArray())); + Assert.That(new[] { "__class__", "__delattr__", "__dict__", "__doc__", "__eq__", "__format__", "__ge__", "__getattribute__", "__gt__", "__hash__", "__init__", "__le__", "__lt__", "__module__", "__ne__", "__new__", "__reduce__", "__reduce_ex__", "__repr__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "__weakref__", "abc", "baz", "classmethod", "foo", "staticfunc" }, Is.EqualTo(ncinstnames.ToArray())); - Assert.AreEqual(fnames.ToArray(), new[] { "foo" }); + Assert.That(new[] { "foo" }, Is.EqualTo(fnames.ToArray())); } [Test] @@ -2070,19 +2070,19 @@ public void ScenarioTokenCategorizer() { categorizer.Initialize(null, source, SourceLocation.MinValue); TokenInfo token = categorizer.ReadToken(); - Assert.AreEqual(token.Category, TokenCategory.Identifier); + Assert.That(TokenCategory.Identifier, Is.EqualTo(token.Category)); token = categorizer.ReadToken(); - Assert.AreEqual(token.Category, TokenCategory.EndOfStream); + Assert.That(TokenCategory.EndOfStream, Is.EqualTo(token.Category)); source = _pe.CreateScriptSourceFromString("\"sys\"", SourceCodeKind.Statements); categorizer.Initialize(null, source, SourceLocation.MinValue); token = categorizer.ReadToken(); - Assert.AreEqual(token.Category, TokenCategory.StringLiteral); + Assert.That(TokenCategory.StringLiteral, Is.EqualTo(token.Category)); token = categorizer.ReadToken(); - Assert.AreEqual(token.Category, TokenCategory.EndOfStream); + Assert.That(TokenCategory.EndOfStream, Is.EqualTo(token.Category)); } private static string ListsToString(IList left, IList right) { @@ -2118,10 +2118,10 @@ def __call__(self): src.Execute(scope); Func t = scope.GetVariable>("inst"); - Assert.AreEqual(42, t()); + Assert.That(t(), Is.EqualTo(42)); t = scope.GetVariable>("instOC"); - Assert.AreEqual(42, t()); + Assert.That(t(), Is.EqualTo(42)); } // ExecuteFile @@ -2184,22 +2184,22 @@ public void Scenario542() { tempFile1.Execute(scope); - Assert.AreEqual(-1, _pe.CreateScriptSourceFromString("M1()").Execute(scope)); - Assert.AreEqual(+1, _pe.CreateScriptSourceFromString("M2()").Execute(scope)); + Assert.That(_pe.CreateScriptSourceFromString("M1()").Execute(scope), Is.EqualTo(-1)); + Assert.That(_pe.CreateScriptSourceFromString("M2()").Execute(scope), Is.EqualTo(+1)); - Assert.AreEqual(-1, (int)(object)_pe.CreateScriptSourceFromString("M1()").Execute(scope)); - Assert.AreEqual(+1, (int)(object)_pe.CreateScriptSourceFromString("M2()").Execute(scope)); + Assert.That((int)(object)_pe.CreateScriptSourceFromString("M1()").Execute(scope), Is.EqualTo(-1)); + Assert.That((int)(object)_pe.CreateScriptSourceFromString("M2()").Execute(scope), Is.EqualTo(+1)); _pe.CreateScriptSourceFromString("if M1() != -1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope); _pe.CreateScriptSourceFromString("if M2() != +1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope); _pe.CreateScriptSourceFromString("c = C()", SourceCodeKind.SingleStatement).Execute(scope); - Assert.AreEqual(-1, _pe.CreateScriptSourceFromString("c.M1()").Execute(scope)); - Assert.AreEqual(+1, _pe.CreateScriptSourceFromString("c.M2()").Execute(scope)); + Assert.That(_pe.CreateScriptSourceFromString("c.M1()").Execute(scope), Is.EqualTo(-1)); + Assert.That(_pe.CreateScriptSourceFromString("c.M2()").Execute(scope), Is.EqualTo(+1)); - Assert.AreEqual(-1, (int)(object)_pe.CreateScriptSourceFromString("c.M1()").Execute(scope)); - Assert.AreEqual(+1, (int)(object)_pe.CreateScriptSourceFromString("c.M2()").Execute(scope)); + Assert.That((int)(object)_pe.CreateScriptSourceFromString("c.M1()").Execute(scope), Is.EqualTo(-1)); + Assert.That((int)(object)_pe.CreateScriptSourceFromString("c.M2()").Execute(scope), Is.EqualTo(+1)); _pe.CreateScriptSourceFromString("if c.M1() != -1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope); _pe.CreateScriptSourceFromString("if c.M2() != +1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope); @@ -2220,8 +2220,8 @@ public void Scenario542() { public void Scenario167() { ScriptScope scope = _env.CreateScope(); _pe.CreateScriptSourceFromString("a=1\r\nb=-1", SourceCodeKind.Statements).Execute(scope); - Assert.AreEqual(1, _pe.CreateScriptSourceFromString("a").Execute(scope)); - Assert.AreEqual(-1, _pe.CreateScriptSourceFromString("b").Execute(scope)); + Assert.That(_pe.CreateScriptSourceFromString("a").Execute(scope), Is.EqualTo(1)); + Assert.That(_pe.CreateScriptSourceFromString("b").Execute(scope), Is.EqualTo(-1)); } // AddToPath @@ -2279,7 +2279,7 @@ public void ScenarioPartialTrust() { // execute some simple code ScriptScope scope = engine.CreateScope(); ScriptSource source = engine.CreateScriptSourceFromString("2 + 2"); - Assert.AreEqual(source.Execute(scope), 4); + Assert.That(4, Is.EqualTo(source.Execute(scope))); // import all of the built-in modules & make sure we can reflect on them... source = engine.CreateScriptSourceFromString(@" @@ -2356,7 +2356,7 @@ public void ScenarioStackFrameLineInfo() { TestLineInfo(scope, lineNumber); // Ensure that all APIs work - Assert.AreEqual(scope.GetVariable("x"), 1); + Assert.That(1, Is.EqualTo(scope.GetVariable("x"))); //IntIntDelegate d = pe.CreateLambda("arg + x"); // Assert.AreEqual(d(100), 101); @@ -2389,9 +2389,9 @@ public void ScenarioCompileAndRun() { compiledCode = _pe.CreateScriptSourceFromString("f()").Compile(); compiledCode.Execute(scope); - Assert.AreEqual(10, clsPart.Field); + Assert.That(clsPart.Field, Is.EqualTo(10)); compiledCode.Execute(scope); - Assert.AreEqual(20, clsPart.Field); + Assert.That(clsPart.Field, Is.EqualTo(20)); } // [Test] // https://github.com/IronLanguages/ironpython3/issues/906 @@ -2415,7 +2415,7 @@ public void ScenarioStreamRedirect() { stdin.Write(bytes, 0, bytes.Length); stdin.Position = 0; _pe.CreateScriptSourceFromString("output = sys.__stdin__.readline()", SourceCodeKind.Statements).Execute(scope); - Assert.AreEqual(str, _pe.CreateScriptSourceFromString("output").Execute(scope)); + Assert.That(_pe.CreateScriptSourceFromString("output").Execute(scope), Is.EqualTo(str)); _pe.CreateScriptSourceFromString("sys.__stdout__.write(output)", SourceCodeKind.Statements).Execute(scope); stdout.Flush(); @@ -2424,7 +2424,7 @@ public void ScenarioStreamRedirect() { // deals with BOM: using (StreamReader reader = new StreamReader(stdout, true)) { string s = reader.ReadToEnd(); - Assert.AreEqual(str, s); + Assert.That(s, Is.EqualTo(str)); } _pe.CreateScriptSourceFromString("sys.__stderr__.write(\"This is stderr\")", SourceCodeKind.Statements).Execute(scope); @@ -2435,7 +2435,7 @@ public void ScenarioStreamRedirect() { // deals with BOM: using (StreamReader reader = new StreamReader(stderr, true)) { string s = reader.ReadToEnd(); - Assert.AreEqual("This is stderr", s); + Assert.That(s, Is.EqualTo("This is stderr")); } } finally { _pe.Runtime.IO.RedirectToConsole(); @@ -2616,14 +2616,14 @@ private static Action VerifyStringKey(int value) { if (!dict.Contains(key)) { Console.WriteLine(PythonOps.Repr(DefaultContext.Default, dict)); } - Assert.True(dict.Contains(key)); - Assert.AreEqual((string)dict[key], key); + Assert.That(dict.Contains(key)); + Assert.That(key, Is.EqualTo((string)dict[key])); }; } private static Action VerifyNoKeys(int value) { return (dict) => { - Assert.AreEqual(dict.Count, 0); + Assert.That(0, Is.EqualTo(dict.Count)); }; } @@ -2765,7 +2765,7 @@ void Test1() { var engine = Python.CreateEngine(); engine.Runtime.IO.SetOutput(memoryStream, Encoding.UTF8); engine.Execute("print('Hello world')"); - Assert.AreEqual(Encoding.UTF8.GetString(memoryStream.ToArray()).Trim(), "Hello world"); + Assert.That("Hello world", Is.EqualTo(Encoding.UTF8.GetString(memoryStream.ToArray()).Trim())); } void Test2() { @@ -2774,7 +2774,7 @@ void Test2() { var engine = Python.CreateEngine(); engine.Runtime.IO.SetOutput(memoryStream, writer); engine.Execute("print('Hello world')"); - Assert.AreEqual(Encoding.UTF8.GetString(memoryStream.ToArray()).Trim(), "Hello world"); + Assert.That("Hello world", Is.EqualTo(Encoding.UTF8.GetString(memoryStream.ToArray()).Trim())); } } } diff --git a/Src/IronPythonTest/IronPythonTest.csproj b/Src/IronPythonTest/IronPythonTest.csproj index ed1fe9d3a..95d56194d 100644 --- a/Src/IronPythonTest/IronPythonTest.csproj +++ b/Src/IronPythonTest/IronPythonTest.csproj @@ -1,7 +1,7 @@  - net462;netcoreapp3.1;net6.0;net7.0 + net462;netcoreapp3.1;net6.0;net8.0 false true @@ -17,8 +17,8 @@ - - + + diff --git a/Src/IronPythonTest/Stress/Engine.cs b/Src/IronPythonTest/Stress/Engine.cs index 176671a96..c71228736 100644 --- a/Src/IronPythonTest/Stress/Engine.cs +++ b/Src/IronPythonTest/Stress/Engine.cs @@ -48,7 +48,7 @@ public void ScenarioXGC() { ScriptScope scope = _pe.CreateScope(); scope.SetVariable("x", "Hello"); _pe.CreateScriptSourceFromFile(System.IO.Path.Combine(Common.InputTestDirectory, "simpleCommand.py")).Execute(scope); - Assert.AreEqual(_pe.CreateScriptSourceFromString("x").Execute(scope), 1); + Assert.That(1, Is.EqualTo(_pe.CreateScriptSourceFromString("x").Execute(scope))); scope = null; } diff --git a/Src/Scripts/generate_alltypes.py b/Src/Scripts/generate_alltypes.py index 3d8721a0b..75514671c 100644 --- a/Src/Scripts/generate_alltypes.py +++ b/Src/Scripts/generate_alltypes.py @@ -30,6 +30,19 @@ def __init__(self, type): except: self.is_float = True + try: + class _(type): pass + self.is_extensible = True + except: + self.is_extensible = False + + if self.is_float: + self.cast_type = "double" + elif self.max > Int32.MaxValue: + self.cast_type = "BigInteger" + else: + self.cast_type = "int" + def get_dict(self): toObj = "(%s)" % self.name toObjFooter = "" @@ -107,6 +120,9 @@ def is_implicit(self, oty): unchecked_cast_method = """ public static %(cast_type)s %(method_name)s(%(type)s x) => unchecked((%(cast_type)s)x);""" +getnewargs_method = """ +public static PythonTuple __getnewargs__(%(type)s self) => PythonTuple.MakeTuple(unchecked((%(cast_type)s)self));""" + identity_method = """ [SpecialName] public static %(type)s %(method_name)s(%(type)s x) => x;""" @@ -173,17 +189,17 @@ def gen_unaryops(cw, ty): cw.writeline() cw.write('public static string __repr__(%s x) => x.ToString(CultureInfo.InvariantCulture);' % (ty.name)) + # for extensible types, this is handled in another Ops file + if not ty.is_extensible: + cw.write(getnewargs_method, type=ty.name, cast_type=ty.cast_type) + if ty.is_float: cw.write(float_trunc, type=ty.name) else: cw.write(simple_identity_method, type=ty.name, method_name="__trunc__") - if ty.max > Int32.MaxValue: - cw.write(unchecked_cast_method, type=ty.name, method_name="__int__", cast_type="BigInteger") - cw.write(unchecked_cast_method, type=ty.name, method_name="__index__", cast_type="BigInteger") - else: - cw.write(unchecked_cast_method, type=ty.name, method_name="__int__", cast_type="int") - cw.write(unchecked_cast_method, type=ty.name, method_name="__index__", cast_type="int") + cw.write(unchecked_cast_method, type=ty.name, method_name="__int__", cast_type=ty.cast_type) + cw.write(unchecked_cast_method, type=ty.name, method_name="__index__", cast_type=ty.cast_type) cw.writeline() cw.enter_block('public static int __hash__(%s x)' % (ty.name)) diff --git a/Tests/modules/network_related/test__ssl.py b/Tests/modules/network_related/test__ssl.py index 31a0bc797..e4a6cf1b5 100644 --- a/Tests/modules/network_related/test__ssl.py +++ b/Tests/modules/network_related/test__ssl.py @@ -15,7 +15,7 @@ from iptest import IronPythonTestCase, is_cli, is_netcoreapp, retryOnFailure, run_test, skipUnlessIronPython SSL_URL = "www.python.org" -SSL_ISSUER = "CN=GlobalSign Atlas R3 DV TLS CA 2023 Q2, O=GlobalSign nv-sa, C=BE" +SSL_ISSUER = "CN=GlobalSign Atlas R3 DV TLS CA 2024 Q2, O=GlobalSign nv-sa, C=BE" SSL_SERVER = "www.python.org" SSL_PORT = 443 SSL_REQUEST = b"GET /en-us HTTP/1.0\r\nHost: www.python.org\r\n\r\n" diff --git a/Tests/test_cliclass.py b/Tests/test_cliclass.py index ee037177f..0306a9205 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_net70, is_netcoreapp, is_netcoreapp21, is_posix, big, run_test, skipUnlessIronPython +from iptest import IronPythonTestCase, is_cli, is_debug, is_mono, is_net70, is_net80, is_netcoreapp, is_netcoreapp21, is_posix, big, run_test, skipUnlessIronPython if is_cli: import clr @@ -1191,14 +1191,15 @@ def test_serialization(self): System.Int32(1), System.UInt32(1), System.Int16(1), System.UInt16(1), System.Byte(1), System.SByte(1), - #System.IntPtr(-1), System.UIntPtr(2), # TODO: IntPtrOps.cs + System.IntPtr(-1), + None if is_mono else System.UIntPtr(2), # fails to deserialize on Mono... System.Decimal(1), System.Single(1.0), System.Char.MaxValue, System.DBNull.Value, System.DateTime.Now, None, {}, (), [], {'a': 2}, (42, ), [42, ], System.StringSplitOptions.RemoveEmptyEntries, ] - if is_netcoreapp and not is_netcoreapp21: + if is_netcoreapp and not is_netcoreapp21 and not is_net80: clr.AddReference("System.Text.Json") data.append(System.Text.Json.JsonValueKind.Object) # byte-based enum @@ -1242,9 +1243,14 @@ def __init__(self): data.append(d1) data.append(d2) + if hasattr(clr, "Serialize"): + clr_roundtrip = lambda x: clr.Deserialize(*clr.Serialize(x)) + else: + clr_roundtrip = lambda x: x + for value in data: # use cPickle & clr.Serialize/Deserialize directly - for newVal in (pickle.loads(pickle.dumps(value)), clr.Deserialize(*clr.Serialize(value))): + for newVal in (pickle.loads(pickle.dumps(value)), clr_roundtrip(value)): self.assertEqual(type(newVal), type(value)) try: self.assertEqual(newVal, value) @@ -1254,38 +1260,40 @@ def __init__(self): self.assertTrue(type(newVal) is list or type(newVal) is dict) # passing an unknown format raises... - self.assertRaises(ValueError, clr.Deserialize, "unknown", "foo") + if hasattr(clr, "Deserialize"): + self.assertRaises(ValueError, clr.Deserialize, "unknown", "foo") - al = System.Collections.ArrayList() - al.Add(2) + if not is_net80: + al = System.Collections.ArrayList() + al.Add(2) - gl = System.Collections.Generic.List[int]() - gl.Add(2) + gl = System.Collections.Generic.List[int]() + gl.Add(2) - # lists... - for value in (al, gl): - for newX in (pickle.loads(pickle.dumps(value)), clr.Deserialize(*clr.Serialize(value))): - self.assertEqual(value.Count, newX.Count) - for i in range(value.Count): - self.assertEqual(value[i], newX[i]) + # lists... + for value in (al, gl): + for newX in (pickle.loads(pickle.dumps(value)), clr_roundtrip(value)): + self.assertEqual(value.Count, newX.Count) + for i in range(value.Count): + self.assertEqual(value[i], newX[i]) - ht = System.Collections.Hashtable() - ht['foo'] = 'bar' + ht = System.Collections.Hashtable() + ht['foo'] = 'bar' - gd = System.Collections.Generic.Dictionary[str, str]() - gd['foo'] = 'bar' + gd = System.Collections.Generic.Dictionary[str, str]() + gd['foo'] = 'bar' - # dictionaries - for value in (ht, gd): - for newX in (pickle.loads(pickle.dumps(value)), clr.Deserialize(*clr.Serialize(value))): - self.assertEqual(value.Count, newX.Count) - for key in value.Keys: - self.assertEqual(value[key], newX[key]) + # dictionaries + for value in (ht, gd): + for newX in (pickle.loads(pickle.dumps(value)), clr_roundtrip(value)): + self.assertEqual(value.Count, newX.Count) + for key in value.Keys: + self.assertEqual(value[key], newX[key]) - # interesting cases - for tempX in [System.Exception("some message")]: - for newX in (pickle.loads(pickle.dumps(tempX)), clr.Deserialize(*clr.Serialize(tempX))): - self.assertEqual(newX.Message, tempX.Message) + # interesting cases + for tempX in [System.Exception("some message")]: + for newX in (pickle.loads(pickle.dumps(tempX)), clr_roundtrip(tempX)): + self.assertEqual(newX.Message, tempX.Message) try: exec(" print 1") @@ -1301,13 +1309,13 @@ class K(System.Exception): other = "something else" tempX = K() #CodePlex 16415 - #for newX in (cPickle.loads(cPickle.dumps(tempX)), clr.Deserialize(*clr.Serialize(tempX))): + #for newX in (pickle.loads(pickle.dumps(tempX)), clr_roundtrip(tempX)): # self.assertEqual(newX.Message, tempX.Message) # self.assertEqual(newX.other, tempX.other) #CodePlex 16415 tempX = System.Exception - #for newX in (cPickle.loads(cPickle.dumps(System.Exception)), clr.Deserialize(*clr.Serialize(System.Exception))): + #for newX in (pickle.loads(pickle.dumps(tempX)), clr_roundtrip(tempX)): # temp_except = newX("another message") # self.assertEqual(temp_except.Message, "another message") @@ -1421,7 +1429,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 + @unittest.skipIf(is_net70 or is_net80, "TODO") # TODO: https://github.com/IronLanguages/ironpython3/issues/1485 def test_int32_bigint_equivalence(self): import math @@ -2057,6 +2065,4 @@ def test_extension_method(self): os.unlink(fname) sys.path = [x for x in old_path] - - run_test(__name__) diff --git a/Tests/test_int.py b/Tests/test_int.py index 34ab61d16..e2c60e145 100644 --- a/Tests/test_int.py +++ b/Tests/test_int.py @@ -4,7 +4,7 @@ import sys -from iptest import IronPythonTestCase, is_cli, is_net70, is_netstandard, is_mono, big, myint, skipUnlessIronPython, run_test +from iptest import IronPythonTestCase, is_cli, is_net70, is_net80, 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,7 +27,7 @@ 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'}) - if is_net70: # https://github.com/IronLanguages/ironpython3/issues/1485 + if is_net70 or is_net80: # 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) diff --git a/Tests/test_methodbinder1.py b/Tests/test_methodbinder1.py index d5b2e41a6..b670dc856 100644 --- a/Tests/test_methodbinder1.py +++ b/Tests/test_methodbinder1.py @@ -8,7 +8,7 @@ import unittest -from iptest import IronPythonTestCase, is_mono, is_net70, is_netcoreapp, run_test, skipUnlessIronPython +from iptest import IronPythonTestCase, is_mono, is_net70, is_net80, is_netcoreapp, run_test, skipUnlessIronPython from iptest.type_util import * from System import Int32 @@ -176,7 +176,7 @@ def test_this_matrix(self): - ch2bi = True if is_net70 else TypeE # .NET 7 adds an implicit cast from Char to BigInteger + ch2bi = True if is_net70 or is_net80 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 diff --git a/make.ps1 b/make.ps1 index 6e2472979..04c915822 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','net7.0'), + [String[]] $frameworks=@('net462','netcoreapp3.1','net6.0','net8.0'), [String] $platform = "x64", [switch] $runIgnored, [int] $jobs = [System.Environment]::ProcessorCount