diff --git a/Src/IronPython.Modules/_socket.cs b/Src/IronPython.Modules/_socket.cs index 65e7ec635..a683fa2e1 100644 --- a/Src/IronPython.Modules/_socket.cs +++ b/Src/IronPython.Modules/_socket.cs @@ -417,7 +417,7 @@ public Bytes recv(int bufsize, int flags = 0) { try { bytesRead = _socket.Receive(buffer, bufsize, (SocketFlags)flags); } catch (Exception e) { - throw MakeRecvException(e, SocketError.NotConnected); + throw MakeException(_context, e); } var bytes = new byte[bytesRead]; @@ -453,7 +453,7 @@ public int recv_into([NotNone] IBufferProtocol buffer, int nbytes = 0, int flags try { bytesRead = _socket.Receive(byteBuffer, nbytes, (SocketFlags)flags); } catch (Exception e) { - throw MakeRecvException(e, SocketError.NotConnected); + throw MakeException(_context, e); } byteBuffer.AsSpan(0, bytesRead).CopyTo(span); @@ -490,7 +490,7 @@ public PythonTuple recvfrom(int bufsize, int flags = 0) { try { bytesRead = _socket.ReceiveFrom(buffer, bufsize, (SocketFlags)flags, ref remoteEP); } catch (Exception e) { - throw MakeRecvException(e, SocketError.InvalidArgument); + throw MakeException(_context, e); } var bytes = new byte[bytesRead]; @@ -523,7 +523,7 @@ public PythonTuple recvfrom_into([NotNone] IBufferProtocol buffer, int nbytes = try { bytesRead = _socket.ReceiveFrom(byteBuffer, nbytes, (SocketFlags)flags, ref remoteEP); } catch (Exception e) { - throw MakeRecvException(e, SocketError.InvalidArgument); + throw MakeException(_context, e); } byteBuffer.AsSpan(0, bytesRead).CopyTo(span); @@ -555,18 +555,6 @@ private static int byteBufferSize(string funcName, int nbytes, int bufLength, in } } - private Exception MakeRecvException(Exception e, SocketError errorCode = SocketError.InvalidArgument) { - if (e is ObjectDisposedException) return MakeException(_context, e); - - // on the socket recv throw a special socket error code when SendTimeout is zero - if (_socket.SendTimeout == 0) { - var s = new SocketException((int)errorCode); - return PythonExceptions.CreateThrowable(error, (int)errorCode, s.Message); - } else { - return MakeException(_context, e); - } - } - [Documentation("send(string[, flags]) -> bytes_sent\n\n" + "Send data to the remote socket. The socket must be connected to a remote\n" + "socket (by calling either connect() or accept(). Returns the number of bytes\n" @@ -734,8 +722,9 @@ public void settimeout(object? timeout) { _socket.SendTimeout = (int)(seconds * MillisecondsPerSecond); _timeout = (int)(seconds * MillisecondsPerSecond); } - } finally { _socket.ReceiveTimeout = _socket.SendTimeout; + } catch (ObjectDisposedException ex) { + throw MakeException(_context, ex); } } @@ -1595,7 +1584,6 @@ public static void setdefaulttimeout(CodeContext/*!*/ context, object? timeout) public const int EAI_SERVICE = (int)SocketError.TypeNotFound; public const int EAI_SOCKTYPE = (int)SocketError.SocketNotSupported; public const int EAI_SYSTEM = (int)SocketError.SocketError; // TODO: not on windows? - public const int EBADF = (int)0x9; // TODO: not in _socket in CPython, can we remove it? public const int INADDR_ALLHOSTS_GROUP = unchecked((int)0xe0000001); public const int INADDR_ANY = (int)0x00000000; public const int INADDR_BROADCAST = unchecked((int)0xFFFFFFFF); @@ -1717,17 +1705,19 @@ public static void setdefaulttimeout(CodeContext/*!*/ context, object? timeout) /// internal static Exception MakeException(CodeContext/*!*/ context, Exception exception) { // !!! this shouldn't just blindly set the type to error (see summary) - if (exception is SocketException) { - SocketException se = (SocketException)exception; + if (exception is SocketException se) { switch (se.SocketErrorCode) { case SocketError.NotConnected: // CPython times out when the socket isn't connected. case SocketError.TimedOut: return PythonExceptions.CreateThrowable(timeout(context), (int)se.SocketErrorCode, se.Message); + case SocketError.WouldBlock: + return PythonExceptions.CreateThrowable(error, se.ErrorCode, se.Message); default: return PythonExceptions.CreateThrowable(error, (int)se.SocketErrorCode, se.Message); } } else if (exception is ObjectDisposedException) { - return PythonExceptions.CreateThrowable(error, (int)EBADF, "the socket is closed"); + const int EBADF = 0x9; + return PythonExceptions.CreateThrowable(error, EBADF, "the socket is closed"); } else if (exception is InvalidOperationException) { return MakeException(context, new SocketException((int)SocketError.InvalidArgument)); } else { diff --git a/Src/IronPython.Modules/nt.cs b/Src/IronPython.Modules/nt.cs index ae4db2245..c056d02df 100644 --- a/Src/IronPython.Modules/nt.cs +++ b/Src/IronPython.Modules/nt.cs @@ -201,6 +201,24 @@ static bool IsWindows() { public static Bytes _getfullpathname(CodeContext/*!*/ context, [NotNone] Bytes path) => _getfullpathname(context, path.ToFsString()).ToFsBytes(); + public static object _getfullpathname(CodeContext/*!*/ context, object? path) { + if (path is IBufferProtocol bp) { + PythonOps.Warn(context, PythonExceptions.DeprecationWarning, "{0}: {1} should be string, bytes or os.PathLike, not {2}", nameof(_getfullpathname), nameof(path), PythonOps.GetPythonTypeName(path)); + return _getfullpathname(context, new Bytes(bp)); + } + + if (PythonOps.TryToFsPath(context, path, out var res)) { + switch (res) { + case string s: return _getfullpathname(context, s); + case Extensible es: return _getfullpathname(context, es.Value); + case Bytes b: return _getfullpathname(context, b); + default: throw new InvalidOperationException(); + } + } + + throw PythonOps.TypeError("{0}: {1} should be string, bytes or os.PathLike, not {2}", nameof(_getfullpathname), nameof(path), PythonOps.GetPythonTypeName(path)); + } + #if FEATURE_PROCESS public static void abort() { System.Environment.FailFast("IronPython os.abort"); @@ -267,8 +285,8 @@ public static bool access(CodeContext context, [NotNone] Bytes path, int mode, [ => access(context, path.ToFsString(), mode, kwargs); [Documentation("")] - public static bool access(CodeContext context, [NotNone] IBufferProtocol path, int mode, [ParamDictionary, NotNone] IDictionary kwargs) - => access(context, path.ToFsBytes(context), mode, kwargs); + public static bool access(CodeContext context, object? path, int mode, [ParamDictionary, NotNone] IDictionary kwargs) + => access(context, ConvertToFsString(context, path, nameof(path)), mode, kwargs); #if FEATURE_FILESYSTEM @@ -287,8 +305,8 @@ public static void chdir([NotNone] string path) { public static void chdir([NotNone] Bytes path) => chdir(path.ToFsString()); - public static void chdir(CodeContext context, [NotNone] IBufferProtocol path) - => chdir(path.ToFsBytes(context)); + public static void chdir(CodeContext context, object? path) + => chdir(ConvertToFsString(context, path, nameof(path))); // Isolate Mono.Unix from the rest of the method so that we don't try to load the Mono.Unix assembly on Windows. private static void chmodUnix(string path, int mode) { @@ -332,8 +350,8 @@ public static void chmod([NotNone] Bytes path, int mode, [ParamDictionary, NotNo => chmod(path.ToFsString(), mode, kwargs); [Documentation("")] - public static void chmod(CodeContext context, [NotNone] IBufferProtocol path, int mode, [ParamDictionary, NotNone] IDictionary kwargs) - => chmod(path.ToFsBytes(context), mode, kwargs); + public static void chmod(CodeContext context, object? path, int mode, [ParamDictionary, NotNone] IDictionary kwargs) + => chmod(ConvertToFsString(context, path, nameof(path)), mode, kwargs); #endif @@ -438,7 +456,7 @@ public static void _exit(CodeContext/*!*/ context, int status) { } public static object fspath(CodeContext context, [AllowNull] object path) - => PythonOps.FsPath(path); + => PythonOps.FsPath(context, path); [LightThrowing] public static object fstat(CodeContext/*!*/ context, int fd) { @@ -571,8 +589,8 @@ public static PythonList listdir(CodeContext context, [NotNone] Bytes path) { return ret; } - public static PythonList listdir(CodeContext context, [NotNone] IBufferProtocol path) - => listdir(context, path.ToFsBytes(context)); + public static PythonList listdir(CodeContext context, [NotNone] object path) + => listdir(context, ConvertToFsString(context, path, nameof(path), orType: "None")); public static BigInteger lseek(CodeContext context, int filedes, long offset, int whence) { var file = context.LanguageContext.FileManager.GetFileFromId(context.LanguageContext, filedes); @@ -596,10 +614,9 @@ public static object lstat([NotNone] string path, [ParamDictionary, NotNone] IDi public static object lstat([NotNone] Bytes path, [ParamDictionary, NotNone] IDictionary kwargs) => lstat(path.ToFsString(), kwargs); - [LightThrowing, Documentation("")] - public static object lstat(CodeContext context, [NotNone] IBufferProtocol path, [ParamDictionary, NotNone] IDictionary kwargs) - => lstat(path.ToFsBytes(context), kwargs); + public static object lstat(CodeContext context, object? path, [ParamDictionary, NotNone] IDictionary kwargs) + => lstat(ConvertToFsString(context, path, nameof(path)), kwargs); [PythonType] public sealed class DirEntry { @@ -625,7 +642,7 @@ internal DirEntry(FileSystemInfo info, bool asBytes) { public bool is_file(bool follow_symlinks = true) => !is_dir(); - public bool is_symlink() => throw new NotImplementedException(); + public bool is_symlink() => info.Attributes.HasFlag(FileAttributes.ReparsePoint) ? throw new NotImplementedException() : false; [LightThrowing] public object? stat(bool follow_symlinks = true) => PythonNT.stat(info.FullName, new Dictionary()); @@ -666,8 +683,8 @@ internal ScandirIterator(IEnumerable list, bool asBytes) { public static ScandirIterator scandir(CodeContext context, string? path = null) => new ScandirIterator(ScandirHelper(context, path), asBytes: false); - public static ScandirIterator scandir(CodeContext context, [NotNone] IBufferProtocol path) - => new ScandirIterator(ScandirHelper(context, ConvertToFsString(context, path, nameof(path))), asBytes: true); + public static ScandirIterator scandir(CodeContext context, [NotNone] object path) + => new ScandirIterator(ScandirHelper(context, ConvertToFsString(context, path, nameof(path), orType: "None")), asBytes: true); private static IEnumerable ScandirHelper(CodeContext context, string? path) { if (path == null) { @@ -815,8 +832,8 @@ public static void mkdir([NotNone] Bytes path, [ParamDictionary, NotNone] IDicti => mkdir(path.ToFsString(), kwargs, args); [Documentation("")] - public static void mkdir(CodeContext context, [NotNone] IBufferProtocol path, [ParamDictionary, NotNone] IDictionary kwargs, [NotNone] params object[] args) - => mkdir(path.ToFsBytes(context), kwargs, args); + public static void mkdir(CodeContext context, object? path, [ParamDictionary, NotNone] IDictionary kwargs, [NotNone] params object[] args) + => mkdir(ConvertToFsString(context, path, nameof(path)), kwargs, args); private const int DefaultBufferSize = 4096; @@ -880,8 +897,8 @@ public static object open(CodeContext context, [NotNone] Bytes filename, int fla => open(context, filename.ToFsString(), flags, kwargs, args); [Documentation("")] - public static object open(CodeContext context, [NotNone] IBufferProtocol filename, int flags, [ParamDictionary, NotNone] IDictionary kwargs, [NotNone] params object[] args) - => open(context, filename.ToFsBytes(context), flags, kwargs, args); + public static object open(CodeContext context, object? path, int flags, [ParamDictionary, NotNone] IDictionary kwargs, [NotNone] params object[] args) + => open(context, ConvertToFsString(context, path, nameof(path)), flags, kwargs, args); private static FileOptions FileOptionsFromFlags(int flag) { @@ -1056,8 +1073,8 @@ public static void rmdir([NotNone] Bytes path, [ParamDictionary, NotNone] IDicti => rmdir(path.ToFsString(), kwargs); [Documentation("")] - public static void rmdir(CodeContext context, [NotNone] IBufferProtocol path, [ParamDictionary, NotNone] IDictionary kwargs) - => rmdir(path.ToFsBytes(context), kwargs); + public static void rmdir(CodeContext context, object? path, [ParamDictionary, NotNone] IDictionary kwargs) + => rmdir(ConvertToFsString(context, path, nameof(path)), kwargs); #if FEATURE_PROCESS @@ -1078,8 +1095,8 @@ public static object spawnv(CodeContext/*!*/ context, int mode, [NotNone] string public static object spawnv(CodeContext context, int mode, [NotNone] Bytes path, object? args) => spawnv(context, mode, path.ToFsString(), args); - public static object spawnv(CodeContext context, int mode, [NotNone] IBufferProtocol path, object? args) - => spawnv(context, mode, path.ToFsBytes(context), args); + public static object spawnv(CodeContext context, int mode, object? path, object? args) + => spawnv(context, mode, ConvertToFsString(context, path, nameof(path)), args); /// /// spawns a new process. @@ -1101,8 +1118,8 @@ public static object spawnve(CodeContext/*!*/ context, int mode, [NotNone] strin public static object spawnve(CodeContext context, int mode, [NotNone] Bytes path, object? args, object? env) => spawnve(context, mode, path.ToFsString(), args, env); - public static object spawnve(CodeContext context, int mode, [NotNone] IBufferProtocol path, object? args, object? env) - => spawnve(context, mode, path.ToFsBytes(context), args, env); + public static object spawnve(CodeContext context, int mode, object? path, object? args, object? env) + => spawnve(context, mode, ConvertToFsString(context, path, nameof(path)), args, env); private static Process MakeProcess() { try { @@ -1212,25 +1229,25 @@ private static string ArgumentsToString(CodeContext/*!*/ context, object? args, #if FEATURE_PROCESS [SupportedOSPlatform("windows"), PythonHidden(PlatformsAttribute.PlatformFamily.Unix)] - public static void startfile([NotNone] string filename, string operation = "open") { + public static void startfile([NotNone] string filepath, string operation = "open") { System.Diagnostics.Process process = new System.Diagnostics.Process(); - process.StartInfo.FileName = filename; + process.StartInfo.FileName = filepath; process.StartInfo.UseShellExecute = true; process.StartInfo.Verb = operation; try { process.Start(); } catch (Exception e) { - throw ToPythonException(e, filename); + throw ToPythonException(e, filepath); } } [SupportedOSPlatform("windows"), PythonHidden(PlatformsAttribute.PlatformFamily.Unix)] - public static void startfile([NotNone] Bytes filename, string operation = "open") - => startfile(filename.ToFsString(), operation); + public static void startfile([NotNone] Bytes filepath, string operation = "open") + => startfile(filepath.ToFsString(), operation); [SupportedOSPlatform("windows"), PythonHidden(PlatformsAttribute.PlatformFamily.Unix)] - public static void startfile(CodeContext context, [NotNone] IBufferProtocol filename, string operation = "open") - => startfile(filename.ToFsBytes(context), operation); + public static void startfile(CodeContext context, object? filepath, string operation = "open") + => startfile(ConvertToFsString(context, filepath, nameof(filepath)), operation); #endif @@ -1486,8 +1503,16 @@ public static object stat([NotNone] Bytes path, [ParamDictionary, NotNone] IDict => stat(path.ToFsString(), dict); [LightThrowing, Documentation("")] - public static object stat(CodeContext context, [NotNone] IBufferProtocol path, [ParamDictionary, NotNone] IDictionary dict) - => stat(path.ToFsBytes(context), dict); + public static object stat(CodeContext context, object? path, [ParamDictionary, NotNone] IDictionary dict) { + if (PythonOps.TryToIndex(path, out BigInteger bi)) { + if (bi.AsInt32(out int i)) { + return stat(context, i); + } + throw PythonOps.OverflowError("fd is greater than maximum"); + } + + return stat(ConvertToFsString(context, path, nameof(path), orType: "integer"), dict); + } [LightThrowing, Documentation("")] public static object stat(CodeContext context, int fd) @@ -1606,9 +1631,16 @@ public static void truncate(CodeContext context, [NotNone] Bytes path, BigIntege => truncate(context, path.ToFsString(), length); [Documentation("")] - public static void truncate(CodeContext context, [NotNone] IBufferProtocol path, BigInteger length) { - PythonOps.Warn(context, PythonExceptions.DeprecationWarning, $"{nameof(truncate)}: {nameof(path)} should be string or bytes, not {PythonOps.GetPythonTypeName(path)}"); // deprecated in 3.6 - truncate(context, path.ToFsBytes(context), length); + public static void truncate(CodeContext context, object? path, BigInteger length) { + if (PythonOps.TryToIndex(path, out BigInteger bi)) { + if (bi.AsInt32(out int i)) { + truncate(context, i, length); + return; + } + throw PythonOps.OverflowError("fd is greater than maximum"); + } + + truncate(context, ConvertToFsString(context, path, nameof(path), orType: "integer"), length); } public static void truncate(CodeContext context, int fd, BigInteger length) @@ -1647,8 +1679,8 @@ public static void remove([NotNone] Bytes path, [ParamDictionary, NotNone] IDict => remove(path.ToFsString(), kwargs); [Documentation("")] - public static void remove(CodeContext context, [NotNone] IBufferProtocol path, [ParamDictionary, NotNone] IDictionary kwargs) - => remove(path.ToFsBytes(context), kwargs); + public static void remove(CodeContext context, object? path, [ParamDictionary, NotNone] IDictionary kwargs) + => remove(ConvertToFsString(context, path, nameof(path)), kwargs); [Documentation("unlink(path, *, dir_fd=None)")] public static void unlink([NotNone] string path, [ParamDictionary, NotNone] IDictionary kwargs) @@ -1659,8 +1691,8 @@ public static void unlink([NotNone] Bytes path, [ParamDictionary, NotNone] IDict => unlink(path.ToFsString(), kwargs); [Documentation("")] - public static void unlink(CodeContext context, [NotNone] IBufferProtocol path, [ParamDictionary, NotNone] IDictionary kwargs) - => unlink(path.ToFsBytes(context), kwargs); + public static void unlink(CodeContext context, object? path, [ParamDictionary, NotNone] IDictionary kwargs) + => unlink(ConvertToFsString(context, path, nameof(path)), kwargs); private static void UnlinkWorker(string path) { if (path == null) { @@ -1812,8 +1844,8 @@ public static void utime([NotNone] Bytes path, [ParamDictionary, NotNone] IDicti => utime(path.ToFsString(), kwargs, args); [Documentation("")] - public static void utime(CodeContext context, [NotNone] IBufferProtocol path, [ParamDictionary, NotNone] IDictionary kwargs, [NotNone] params object[] args) - => utime(path.ToFsBytes(context), kwargs, args); + public static void utime(CodeContext context, object? path, [ParamDictionary, NotNone] IDictionary kwargs, [NotNone] params object[] args) + => utime(ConvertToFsString(context, path, nameof(path)), kwargs, args); #endif @@ -2244,21 +2276,23 @@ private static Exception GetWin32Error(int error, string? filename = null, strin private static Bytes ToFsBytes(this string s) => Bytes.Make(_filesystemEncoding.GetBytes(s)); - private static Bytes ToFsBytes(this IBufferProtocol bp, CodeContext context) { - // TODO: Python 3.6: "path should be string, bytes or os.PathLike" - PythonOps.Warn(context, PythonExceptions.DeprecationWarning, "path should be string or bytes, not {0}", PythonOps.GetPythonTypeName(bp)); - return new Bytes(bp); // accepts FULL_RO buffers in CPython - } - - private static string ConvertToFsString(CodeContext context, [NotNull] object? o, string argname, [CallerMemberName] string? methodname = null) - => o switch { - string s => s, - ExtensibleString es => es.Value, - Bytes b => b.ToFsString(), - IBufferProtocol bp => bp.ToFsBytes(context).ToFsString(), - // TODO: Python 3.6: os.PathLike - _ => throw PythonOps.TypeError("{0}: {1} should be string or bytes, not '{2}'", methodname, argname, PythonOps.GetPythonTypeName(o)) - }; + private static string ConvertToFsString(CodeContext context, object? o, string argname, [CallerMemberName] string? methodname = null, string? orType = null) { + if (o is not Bytes && o is IBufferProtocol bp) { + if (orType is null) + PythonOps.Warn(context, PythonExceptions.DeprecationWarning, "{0}: {1} should be string, bytes or os.PathLike, not {2}", methodname, argname, PythonOps.GetPythonTypeName(o)); + else + PythonOps.Warn(context, PythonExceptions.DeprecationWarning, "{0}: {1} should be string, bytes, os.PathLike or {3}, not {2}", methodname, argname, PythonOps.GetPythonTypeName(o), orType); + o = new Bytes(bp); // accepts FULL_RO buffers in CPython + } + + if (PythonOps.TryToFsPathDecoded(context, o, out var res)) + return res; + + if (orType is null) + throw PythonOps.TypeError("{0}: {1} should be string, bytes or os.PathLike, not {2}", methodname, argname, PythonOps.GetPythonTypeName(o)); + else + throw PythonOps.TypeError("{0}: {1} should be string, bytes, os.PathLike or {3}, not {2}", methodname, argname, PythonOps.GetPythonTypeName(o), orType); + } private static void CheckOptionalArgsCount(int numRegParms, int numOptPosParms, int numKwParms, int numOptPosArgs, int numKwArgs, [CallerMemberName] string? methodname = null) { if (numOptPosArgs > numOptPosParms) diff --git a/Src/IronPython/Runtime/Operations/PythonOps.cs b/Src/IronPython/Runtime/Operations/PythonOps.cs index b3518b6c1..45c4ae26b 100644 --- a/Src/IronPython/Runtime/Operations/PythonOps.cs +++ b/Src/IronPython/Runtime/Operations/PythonOps.cs @@ -325,25 +325,40 @@ public static string FormatString(CodeContext/*!*/ context, string str, object d return StringFormatter.Format(context, str, data); } - internal static object FsPath(object? path) { - if (path is string) return path; - if (path is Extensible) return path; - if (path is Bytes) return path; + internal static object FsPath(CodeContext context, object? path) { + if (TryToFsPath(context, path, out var res)) + return res; + + throw PythonOps.TypeError("expected str, bytes or os.PathLike object, not {0}", PythonOps.GetPythonTypeName(path)); + } - if (PythonTypeOps.TryInvokeUnaryOperator(DefaultContext.Default, path, "__fspath__", out object res)) { - return res switch { - string => res, - Extensible => res, - Bytes => res, - _ => throw PythonOps.TypeError("expected {0}.__fspath__() to return str or bytes, not {0}", PythonOps.GetPythonTypeName(path), PythonOps.GetPythonTypeName(res)) - }; + internal static bool TryToFsPath(CodeContext context, object? path, [NotNullWhen(true)] out object? res) { + res = path; + if (res is string || res is Extensible || res is Bytes) return true; + + if (PythonTypeOps.TryInvokeUnaryOperator(DefaultContext.Default, path, "__fspath__", out res)) { + if (res is string || res is Extensible || res is Bytes) return true; + throw PythonOps.TypeError("expected {0}.__fspath__() to return str or bytes, not {1}", PythonOps.GetPythonTypeName(path), PythonOps.GetPythonTypeName(res)); } - throw PythonOps.TypeError("expected str, bytes or os.PathLike object, not {0}", PythonOps.GetPythonTypeName(path)); + return false; + } + + internal static string FsPathDecoded(CodeContext context, object? path) + => DecodeFsPath(context, FsPath(context, path)); + + internal static bool TryToFsPathDecoded(CodeContext context, object? path, [NotNullWhen(true)] out string? res) { + if (PythonOps.TryToFsPath(context, path, out object? obj)) { + res = DecodeFsPath(context, obj); + return true; + } + + res = null; + return false; } - internal static string FsPathDecoded(CodeContext context, object? path) { - return PythonOps.FsPath(path) switch { + private static string DecodeFsPath(CodeContext context, object obj) { + return obj switch { string s => s, Extensible es => es, Bytes b => b.decode(context, SysModule.getfilesystemencoding(), SysModule.getfilesystemencodeerrors()), diff --git a/Src/IronPythonTest/Cases/CPythonCasesManifest.ini b/Src/IronPythonTest/Cases/CPythonCasesManifest.ini index 74c596a79..f473e537b 100644 --- a/Src/IronPythonTest/Cases/CPythonCasesManifest.ini +++ b/Src/IronPythonTest/Cases/CPythonCasesManifest.ini @@ -1195,9 +1195,6 @@ Ignore=true # two failures [CPython.test_fileinput] Ignore=true # test_errors - https://github.com/IronLanguages/ironpython3/issues/1452 -[CPython.test_genericpath] -Ignore=true # blocked by os.PathLike - [CPython.test_global] Ignore=true # AssertionError: 5 != 4 @@ -1219,9 +1216,6 @@ Ignore=true # two failures [CPython.test_math] Ignore=true # precision? -[CPython.test_ntpath] -Ignore=true # blocked by os.PathLike - [CPython.test_opcodes] Ignore=true # __annotations__ @@ -1260,6 +1254,3 @@ Ignore=true # test_free_after_iterating [CPython.test_uuid] Ignore=true # LookupError: unknown encoding: oem - https://github.com/IronLanguages/ironpython3/issues/1451 - -[CPython.test_zipapp] -Ignore=true # NotImplementedError: The method or operation is not implemented. diff --git a/Src/IronPythonTest/Cases/IronPythonCasesManifest.ini b/Src/IronPythonTest/Cases/IronPythonCasesManifest.ini index 833b72eff..80ff755d1 100644 --- a/Src/IronPythonTest/Cases/IronPythonCasesManifest.ini +++ b/Src/IronPythonTest/Cases/IronPythonCasesManifest.ini @@ -190,9 +190,6 @@ Ignore=true # 1 failure [IronPython.test_sax_stdlib] Ignore=true # multiple failures -[IronPython.test_socket_stdlib] -Ignore=true # blocking - [IronPython.test_ssl_stdlib] Ignore=true # unittest.case.SkipTest: Cannot import name SSLSession diff --git a/Tests/test_socket_stdlib.py b/Tests/test_socket_stdlib.py index fae2951a5..ed3d3adf0 100644 --- a/Tests/test_socket_stdlib.py +++ b/Tests/test_socket_stdlib.py @@ -9,7 +9,7 @@ import unittest import sys -from iptest import is_linux, is_posix, run_test +from iptest import is_linux, is_osx, is_posix, run_test import test.test_socket @@ -80,7 +80,7 @@ def load_tests(loader, standard_tests, pattern): suite.addTest(test.test_socket.FileObjectClassTestCase('testRealClose')) suite.addTest(test.test_socket.FileObjectClassTestCase('testSmallRead')) suite.addTest(test.test_socket.FileObjectClassTestCase('testUnbufferedRead')) - suite.addTest(test.test_socket.GeneralModuleTests('testCloseException')) + suite.addTest(unittest.expectedFailure(test.test_socket.GeneralModuleTests('testCloseException'))) # TODO: figure out suite.addTest(test.test_socket.GeneralModuleTests('testCrucialConstants')) suite.addTest(test.test_socket.GeneralModuleTests('testDefaultTimeout')) suite.addTest(test.test_socket.GeneralModuleTests('testGetServBy')) @@ -183,9 +183,7 @@ def load_tests(loader, standard_tests, pattern): suite.addTest(test.test_socket.NonBlockingTCPTests('testConnect')) suite.addTest(test.test_socket.NonBlockingTCPTests('testInheritFlags')) suite.addTest(test.test_socket.NonBlockingTCPTests('testInitNonBlocking')) - if is_posix: - suite.addTest(unittest.expectedFailure(test.test_socket.NonBlockingTCPTests('testRecv'))) # TODO: figure out - else: + if not is_osx: # TODO: figure out suite.addTest(test.test_socket.NonBlockingTCPTests('testRecv')) suite.addTest(test.test_socket.NonBlockingTCPTests('testSetBlocking')) suite.addTest(test.test_socket.NonBlockingTCPTests('testSetBlocking_overflow')) diff --git a/Tests/test_sqlite3_stdlib.py b/Tests/test_sqlite3_stdlib.py index ff7e7fa49..b6d07bb73 100644 --- a/Tests/test_sqlite3_stdlib.py +++ b/Tests/test_sqlite3_stdlib.py @@ -49,6 +49,7 @@ def load_tests(loader, standard_tests, pattern): #suite.addTest(unittest.expectedFailure(sqlite3.test.dbapi.ConnectionTests('CheckOpenUri'))) suite.addTest(sqlite3.test.dbapi.ConnectionTests('CheckRollback')) suite.addTest(sqlite3.test.dbapi.ConnectionTests('CheckRollbackAfterNoChanges')) + suite.addTest(sqlite3.test.dbapi.ConnectionTests('CheckSameThreadErrorOnOldVersion')) suite.addTest(sqlite3.test.dbapi.CursorTests('CheckArraySize')) suite.addTest(sqlite3.test.dbapi.CursorTests('CheckClose')) suite.addTest(sqlite3.test.dbapi.CursorTests('CheckCursorConnection')) @@ -70,6 +71,7 @@ def load_tests(loader, standard_tests, pattern): suite.addTest(sqlite3.test.dbapi.CursorTests('CheckExecuteManySequence')) suite.addTest(sqlite3.test.dbapi.CursorTests('CheckExecuteManyWrongSqlArg')) suite.addTest(sqlite3.test.dbapi.CursorTests('CheckExecuteNoArgs')) + suite.addTest(unittest.expectedFailure(sqlite3.test.dbapi.CursorTests('CheckExecuteNonIterable'))) suite.addTest(sqlite3.test.dbapi.CursorTests('CheckExecuteParamList')) suite.addTest(unittest.expectedFailure(sqlite3.test.dbapi.CursorTests('CheckExecuteParamSequence'))) suite.addTest(unittest.expectedFailure(sqlite3.test.dbapi.CursorTests('CheckExecuteTooMuchSql'))) @@ -85,6 +87,9 @@ def load_tests(loader, standard_tests, pattern): suite.addTest(sqlite3.test.dbapi.CursorTests('CheckFetchmanyKwArg')) suite.addTest(sqlite3.test.dbapi.CursorTests('CheckFetchone')) suite.addTest(sqlite3.test.dbapi.CursorTests('CheckFetchoneNoStatement')) + suite.addTest(unittest.expectedFailure(sqlite3.test.dbapi.CursorTests('CheckLastRowIDOnReplace'))) + suite.addTest(sqlite3.test.dbapi.CursorTests('CheckLastRowIDOnIgnore')) + suite.addTest(sqlite3.test.dbapi.CursorTests('CheckLastRowIDInsertOR')) suite.addTest(sqlite3.test.dbapi.CursorTests('CheckRowcountExecute')) suite.addTest(sqlite3.test.dbapi.CursorTests('CheckRowcountExecutemany')) suite.addTest(sqlite3.test.dbapi.CursorTests('CheckRowcountSelect')) @@ -111,6 +116,7 @@ def load_tests(loader, standard_tests, pattern): suite.addTest(sqlite3.test.dbapi.ExtensionTests('CheckConnectionExecute')) suite.addTest(sqlite3.test.dbapi.ExtensionTests('CheckConnectionExecutemany')) suite.addTest(unittest.expectedFailure(sqlite3.test.dbapi.ExtensionTests('CheckConnectionExecutescript'))) + suite.addTest(unittest.expectedFailure(sqlite3.test.dbapi.ExtensionTests('CheckCursorExecutescriptAsBytes'))) suite.addTest(sqlite3.test.dbapi.ExtensionTests('CheckScriptErrorNormal')) suite.addTest(unittest.expectedFailure(sqlite3.test.dbapi.ExtensionTests('CheckScriptStringSql'))) suite.addTest(unittest.expectedFailure(sqlite3.test.dbapi.ExtensionTests('CheckScriptSyntaxError'))) @@ -124,19 +130,28 @@ def load_tests(loader, standard_tests, pattern): suite.addTest(unittest.expectedFailure(sqlite3.test.dbapi.ClosedConTests('CheckClosedSetAuthorizer'))) suite.addTest(unittest.expectedFailure(sqlite3.test.dbapi.ClosedConTests('CheckClosedSetProgressCallback'))) suite.addTest(unittest.expectedFailure(sqlite3.test.dbapi.ClosedCurTests('CheckClosed'))) + suite.addTest(sqlite3.test.dbapi.SqliteOnConflictTests('CheckOnConflictAbortRaisesWithExplicitTransactions')) + suite.addTest(sqlite3.test.dbapi.SqliteOnConflictTests('CheckOnConflictAbortRaisesWithoutTransactions')) + suite.addTest(sqlite3.test.dbapi.SqliteOnConflictTests('CheckOnConflictRollbackWithExplicitTransaction')) + suite.addTest(sqlite3.test.dbapi.SqliteOnConflictTests('CheckOnConflictRollbackWithoutTransaction')) + suite.addTest(sqlite3.test.dbapi.SqliteOnConflictTests('CheckOnConflictFail')) + suite.addTest(sqlite3.test.dbapi.SqliteOnConflictTests('CheckOnConflictIgnore')) + suite.addTest(sqlite3.test.dbapi.SqliteOnConflictTests('CheckOnConflictReplace')) suite.addTest(unittest.expectedFailure(sqlite3.test.dump.DumpTests('CheckTableDump'))) suite.addTest(unittest.expectedFailure(sqlite3.test.dump.DumpTests('CheckUnorderableRow'))) #suite.addTest(unittest.expectedFailure(sqlite3.test.factory.ConnectionFactoryTests('CheckIsInstance'))) + suite.addTest(unittest.expectedFailure(sqlite3.test.factory.CursorFactoryTests('CheckInvalidFactory'))) suite.addTest(unittest.expectedFailure(sqlite3.test.factory.CursorFactoryTests('CheckIsInstance'))) suite.addTest(unittest.expectedFailure(sqlite3.test.factory.RowFactoryTestsBackwardsCompat('CheckIsProducedByFactory'))) suite.addTest(sqlite3.test.factory.RowFactoryTests('CheckCustomFactory')) - suite.addTest(sqlite3.test.factory.RowFactoryTests('CheckFakeCursorClass')) + suite.addTest(unittest.expectedFailure(sqlite3.test.factory.RowFactoryTests('CheckFakeCursorClass'))) suite.addTest(sqlite3.test.factory.RowFactoryTests('CheckSqliteRowAsDict')) suite.addTest(unittest.expectedFailure(sqlite3.test.factory.RowFactoryTests('CheckSqliteRowAsSequence'))) suite.addTest(sqlite3.test.factory.RowFactoryTests('CheckSqliteRowAsTuple')) suite.addTest(sqlite3.test.factory.RowFactoryTests('CheckSqliteRowHashCmp')) suite.addTest(unittest.expectedFailure(sqlite3.test.factory.RowFactoryTests('CheckSqliteRowIndex'))) suite.addTest(sqlite3.test.factory.RowFactoryTests('CheckSqliteRowIter')) + suite.addTest(unittest.expectedFailure(sqlite3.test.factory.RowFactoryTests('CheckSqliteRowSlice'))) suite.addTest(sqlite3.test.factory.TextFactoryTests('CheckCustom')) suite.addTest(sqlite3.test.factory.TextFactoryTests('CheckOptimizedUnicode')) suite.addTest(unittest.expectedFailure(sqlite3.test.factory.TextFactoryTests('CheckString'))) @@ -148,8 +163,10 @@ def load_tests(loader, standard_tests, pattern): suite.addTest(unittest.expectedFailure(sqlite3.test.hooks.CollationTests('CheckCollationIsUsed'))) suite.addTest(unittest.expectedFailure(sqlite3.test.hooks.CollationTests('CheckCollationRegisterTwice'))) suite.addTest(unittest.expectedFailure(sqlite3.test.hooks.CollationTests('CheckCollationReturnsLargeInteger'))) + suite.addTest(unittest.expectedFailure(sqlite3.test.hooks.CollationTests('CheckCreateCollationBadUpper'))) suite.addTest(unittest.expectedFailure(sqlite3.test.hooks.CollationTests('CheckCreateCollationNotAscii'))) suite.addTest(unittest.expectedFailure(sqlite3.test.hooks.CollationTests('CheckCreateCollationNotCallable'))) + suite.addTest(unittest.expectedFailure(sqlite3.test.hooks.CollationTests('CheckCreateCollationNotString'))) suite.addTest(unittest.expectedFailure(sqlite3.test.hooks.CollationTests('CheckDeregisterCollation'))) suite.addTest(unittest.expectedFailure(sqlite3.test.hooks.ProgressTests('CheckCancelOperation'))) suite.addTest(unittest.expectedFailure(sqlite3.test.hooks.ProgressTests('CheckClearHandler'))) @@ -159,8 +176,10 @@ def load_tests(loader, standard_tests, pattern): suite.addTest(unittest.expectedFailure(sqlite3.test.hooks.TraceCallbackTests('CheckTraceCallbackUsed'))) suite.addTest(unittest.expectedFailure(sqlite3.test.hooks.TraceCallbackTests('CheckUnicodeContent'))) suite.addTest(sqlite3.test.regression.RegressionTests('CheckAutoCommit')) + suite.addTest(unittest.expectedFailure(sqlite3.test.regression.RegressionTests('CheckBpo31770'))) suite.addTest(unittest.expectedFailure(sqlite3.test.regression.RegressionTests('CheckCollation'))) suite.addTest(sqlite3.test.regression.RegressionTests('CheckColumnNameWithSpaces')) + suite.addTest(unittest.expectedFailure(sqlite3.test.regression.RegressionTests('CheckCommitCursorReset'))) suite.addTest(unittest.expectedFailure(sqlite3.test.regression.RegressionTests('CheckConnectionCall'))) suite.addTest(unittest.expectedFailure(sqlite3.test.regression.RegressionTests('CheckConnectionConstructorCallCheck'))) suite.addTest(unittest.expectedFailure(sqlite3.test.regression.RegressionTests('CheckConvertTimestampMicrosecondPadding'))) @@ -176,14 +195,17 @@ def load_tests(loader, standard_tests, pattern): suite.addTest(sqlite3.test.regression.RegressionTests('CheckPragmaUserVersion')) suite.addTest(unittest.expectedFailure(sqlite3.test.regression.RegressionTests('CheckRecursiveCursorUse'))) suite.addTest(sqlite3.test.regression.RegressionTests('CheckRegisterAdapter')) - suite.addTest(unittest.expectedFailure(sqlite3.test.regression.RegressionTests('CheckSetDict'))) - suite.addTest(sqlite3.test.regression.RegressionTests('CheckSetIsolationLevel')) + suite.addTest(unittest.expectedFailure(sqlite3.test.regression.RegressionTests('CheckSetIsolationLevel'))) suite.addTest(sqlite3.test.regression.RegressionTests('CheckStatementFinalizationOnCloseDb')) suite.addTest(sqlite3.test.regression.RegressionTests('CheckStatementReset')) suite.addTest(unittest.expectedFailure(sqlite3.test.regression.RegressionTests('CheckStrSubclass'))) suite.addTest(unittest.expectedFailure(sqlite3.test.regression.RegressionTests('CheckTypeMapUsage'))) suite.addTest(sqlite3.test.regression.RegressionTests('CheckWorkaroundForBuggySqliteTransferBindings')) - suite.addTest(sqlite3.test.transactions.TransactionTests('CheckDMLdoesAutoCommitBefore')) + suite.addTest(unittest.expectedFailure(sqlite3.test.regression.UnhashableCallbacksTestCase('test_progress_handler'))) + suite.addTest(unittest.expectedFailure(sqlite3.test.regression.UnhashableCallbacksTestCase('test_func'))) + suite.addTest(unittest.expectedFailure(sqlite3.test.regression.UnhashableCallbacksTestCase('test_authorizer'))) + suite.addTest(unittest.expectedFailure(sqlite3.test.regression.UnhashableCallbacksTestCase('test_aggr'))) + suite.addTest(unittest.expectedFailure(sqlite3.test.transactions.TransactionTests('CheckDMLDoesNotAutoCommitBefore'))) suite.addTest(sqlite3.test.transactions.TransactionTests('CheckDeleteStartsTransaction')) suite.addTest(sqlite3.test.transactions.TransactionTests('CheckInsertStartsTransaction')) if is_linux: @@ -196,9 +218,11 @@ def load_tests(loader, standard_tests, pattern): suite.addTest(unittest.expectedFailure(sqlite3.test.transactions.TransactionTests('CheckRollbackCursorConsistency'))) suite.addTest(sqlite3.test.transactions.TransactionTests('CheckToggleAutoCommit')) suite.addTest(sqlite3.test.transactions.TransactionTests('CheckUpdateStartsTransaction')) + suite.addTest(sqlite3.test.transactions.TransactionalDDL('CheckDdlDoesNotAutostartTransaction')) + suite.addTest(unittest.expectedFailure(sqlite3.test.transactions.TransactionalDDL('CheckImmediateTransactionalDDL'))) + suite.addTest(unittest.expectedFailure(sqlite3.test.transactions.TransactionalDDL('CheckTransactionalDDL'))) suite.addTest(sqlite3.test.transactions.SpecialCommandTests('CheckDropTable')) suite.addTest(sqlite3.test.transactions.SpecialCommandTests('CheckPragma')) - suite.addTest(sqlite3.test.transactions.SpecialCommandTests('CheckVacuum')) suite.addTest(unittest.expectedFailure(sqlite3.test.types.SqliteTypeTests('CheckBlob'))) suite.addTest(sqlite3.test.types.SqliteTypeTests('CheckFloat')) suite.addTest(sqlite3.test.types.SqliteTypeTests('CheckLargeInt')) @@ -219,9 +243,13 @@ def load_tests(loader, standard_tests, pattern): suite.addTest(sqlite3.test.types.DeclTypesTests('CheckUnsupportedSeq')) suite.addTest(sqlite3.test.types.ColNamesTests('CheckCaseInConverterName')) suite.addTest(unittest.expectedFailure(sqlite3.test.types.ColNamesTests('CheckColName'))) + suite.addTest(sqlite3.test.types.ColNamesTests('CheckCursorDescriptionInsert')) suite.addTest(sqlite3.test.types.ColNamesTests('CheckCursorDescriptionNoRow')) suite.addTest(sqlite3.test.types.ColNamesTests('CheckDeclTypeNotUsed')) suite.addTest(sqlite3.test.types.ColNamesTests('CheckNone')) + suite.addTest(sqlite3.test.types.CommonTableExpressionTests('CheckCursorDescriptionCTESimple')) + suite.addTest(sqlite3.test.types.CommonTableExpressionTests('CheckCursorDescriptionCTESMultipleColumns')) + suite.addTest(sqlite3.test.types.CommonTableExpressionTests('CheckCursorDescriptionCTE')) suite.addTest(unittest.expectedFailure(sqlite3.test.types.ObjectAdaptationTests('CheckCasterIsUsed'))) suite.addTest(unittest.expectedFailure(sqlite3.test.types.BinaryConverterTests('CheckBinaryInputForConverter'))) suite.addTest(unittest.expectedFailure(sqlite3.test.types.DateTimeTests('CheckDateTimeSubSeconds'))) @@ -237,6 +265,7 @@ def load_tests(loader, standard_tests, pattern): #suite.addTest(unittest.expectedFailure(sqlite3.test.userfunctions.AuthorizerRaiseExceptionTests('test_table_access'))) #suite.addTest(unittest.expectedFailure(sqlite3.test.userfunctions.AuthorizerTests('test_column_access'))) #suite.addTest(unittest.expectedFailure(sqlite3.test.userfunctions.AuthorizerTests('test_table_access'))) + suite.addTest(sqlite3.test.userfunctions.FunctionTests('CheckAnyArguments')) suite.addTest(sqlite3.test.userfunctions.FunctionTests('CheckFuncErrorOnCreate')) suite.addTest(sqlite3.test.userfunctions.FunctionTests('CheckFuncException')) suite.addTest(sqlite3.test.userfunctions.FunctionTests('CheckFuncRefCount')) @@ -259,6 +288,7 @@ def load_tests(loader, standard_tests, pattern): #suite.addTest(unittest.expectedFailure(sqlite3.test.userfunctions.AggregateTests('CheckAggrCheckParamInt'))) #suite.addTest(unittest.expectedFailure(sqlite3.test.userfunctions.AggregateTests('CheckAggrCheckParamNone'))) #suite.addTest(unittest.expectedFailure(sqlite3.test.userfunctions.AggregateTests('CheckAggrCheckParamStr'))) + #suite.addTest(unittest.expectedFailure(sqlite3.test.userfunctions.AggregateTests('CheckAggrCheckParamsInt'))) #suite.addTest(unittest.expectedFailure(sqlite3.test.userfunctions.AggregateTests('CheckAggrErrorOnCreate'))) #suite.addTest(unittest.expectedFailure(sqlite3.test.userfunctions.AggregateTests('CheckAggrExceptionInFinalize'))) #suite.addTest(unittest.expectedFailure(sqlite3.test.userfunctions.AggregateTests('CheckAggrExceptionInInit'))) diff --git a/Tests/test_stdmodules.py b/Tests/test_stdmodules.py index 502f8fc65..9fb99cc20 100644 --- a/Tests/test_stdmodules.py +++ b/Tests/test_stdmodules.py @@ -38,7 +38,7 @@ def test_cp10825(self): for i in range(5): try: - temp_url = urllib.request.urlopen("https://www.python.org") + temp_url = urllib.request.urlopen("http://www.microsoft.com") break except Exception as e: err = e @@ -48,7 +48,7 @@ def test_cp10825(self): if temp_url is None: raise err try: - self.assertTrue(temp_url.url.startswith("https://www.python.org")) + self.assertTrue(temp_url.url.startswith("http://www.microsoft.com")) finally: temp_url.close()