Skip to content

Commit 7687852

Browse files
committed
Merge branch 'master' into 3.6
# Conflicts: # Src/IronPython.Modules/_socket.cs # Tests/test_functools_stdlib.py
2 parents 73c6d61 + 2f10037 commit 7687852

25 files changed

Lines changed: 2043 additions & 348 deletions

Src/IronPython.Modules/_functools.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Collections;
99
using System.Collections.Generic;
1010
using System.Runtime.CompilerServices;
11+
using System.Text;
1112
using System.Threading;
1213

1314
using IronPython.Runtime;
@@ -191,6 +192,24 @@ public void __setstate__(CodeContext context, [NotNone] PythonTuple state) {
191192
}
192193
}
193194

195+
public string __repr__(CodeContext context) {
196+
var builder = new StringBuilder();
197+
builder.Append("functools.partial(");
198+
builder.Append(PythonOps.Repr(context, func));
199+
foreach (var x in _args) {
200+
builder.Append(", ");
201+
builder.Append(PythonOps.Repr(context, x));
202+
}
203+
foreach (var p in _keywordArgs) {
204+
builder.Append(", ");
205+
builder.Append(p.Key);
206+
builder.Append('=');
207+
builder.Append(PythonOps.Repr(context, p.Value));
208+
}
209+
builder.Append(')');
210+
return builder.ToString();
211+
}
212+
194213
#endregion
195214

196215
#region Operator methods

Src/IronPython.Modules/_socket.cs

Lines changed: 221 additions & 44 deletions
Large diffs are not rendered by default.

Src/IronPython.Modules/errno.cs

Lines changed: 741 additions & 208 deletions
Large diffs are not rendered by default.

Src/IronPython.Modules/nt.cs

Lines changed: 30 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,12 +1264,14 @@ public sealed class stat_result : PythonTuple {
12641264
internal stat_result(int mode) : this(new object[10] { mode, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, null) { }
12651265

12661266
internal stat_result(Mono.Unix.Native.Stat stat)
1267-
: this(new object[16] {(int)stat.st_mode, ToInt(stat.st_ino), ToInt(stat.st_dev), ToInt(stat.st_nlink), ToInt(stat.st_uid), ToInt(stat.st_gid), ToInt(stat.st_size), ToInt(stat.st_atime), ToInt(stat.st_mtime), ToInt(stat.st_ctime),
1267+
: this(new object[16] {Mono.Unix.Native.NativeConvert.FromFilePermissions(stat.st_mode), ToInt(stat.st_ino), ToInt(stat.st_dev), ToInt(stat.st_nlink), ToInt(stat.st_uid), ToInt(stat.st_gid), ToInt(stat.st_size),
1268+
ToInt(stat.st_atime), ToInt(stat.st_mtime), ToInt(stat.st_ctime),
12681269
stat.st_atime + stat.st_atime_nsec / (double)nanosecondsPerSeconds, stat.st_mtime + stat.st_mtime_nsec / (double)nanosecondsPerSeconds, stat.st_ctime + stat.st_ctime_nsec / (double)nanosecondsPerSeconds,
12691270
ToInt(stat.st_atime * nanosecondsPerSeconds + stat.st_atime_nsec), ToInt(stat.st_mtime * nanosecondsPerSeconds + stat.st_mtime_nsec), ToInt(stat.st_ctime * nanosecondsPerSeconds + stat.st_ctime_nsec) }, null) { }
12701271

12711272
internal stat_result(int mode, ulong fileidx, long size, long st_atime_ns, long st_mtime_ns, long st_ctime_ns)
1272-
: this(new object[16] { mode, ToInt(fileidx), 0, 0, 0, 0, ToInt(size), ToInt(st_atime_ns / nanosecondsPerSeconds), ToInt(st_mtime_ns / nanosecondsPerSeconds), ToInt(st_ctime_ns / nanosecondsPerSeconds),
1273+
: this(new object[16] { mode, ToInt(fileidx), 0, 0, 0, 0, ToInt(size),
1274+
ToInt(st_atime_ns / nanosecondsPerSeconds), ToInt(st_mtime_ns / nanosecondsPerSeconds), ToInt(st_ctime_ns / nanosecondsPerSeconds),
12731275
st_atime_ns / (double)nanosecondsPerSeconds, st_mtime_ns / (double)nanosecondsPerSeconds, st_ctime_ns / (double)nanosecondsPerSeconds,
12741276
ToInt(st_atime_ns), ToInt(st_mtime_ns), ToInt(st_ctime_ns) }, null) { }
12751277

@@ -1519,54 +1521,30 @@ public static object stat(CodeContext context, int fd)
15191521
=> fstat(context, fd);
15201522

15211523
public static string strerror(int code) {
1522-
switch (code) {
1523-
case 0: return "No error";
1524-
case PythonErrorNumber.E2BIG: return "Arg list too long";
1525-
case PythonErrorNumber.EACCES: return "Permission denied";
1526-
case PythonErrorNumber.EAGAIN: return "Resource temporarily unavailable";
1527-
case PythonErrorNumber.EBADF: return "Bad file descriptor";
1528-
case PythonErrorNumber.EBUSY: return "Resource device";
1529-
case PythonErrorNumber.ECHILD: return "No child processes";
1530-
case PythonErrorNumber.EDEADLK: return "Resource deadlock avoided";
1531-
case PythonErrorNumber.EDOM: return "Domain error";
1532-
case PythonErrorNumber.EDQUOT: return "Unknown error";
1533-
case PythonErrorNumber.EEXIST: return "File exists";
1534-
case PythonErrorNumber.EFAULT: return "Bad address";
1535-
case PythonErrorNumber.EFBIG: return "File too large";
1536-
case PythonErrorNumber.EILSEQ: return "Illegal byte sequence";
1537-
case PythonErrorNumber.EINTR: return "Interrupted function call";
1538-
case PythonErrorNumber.EINVAL: return "Invalid argument";
1539-
case PythonErrorNumber.EIO: return "Input/output error";
1540-
case PythonErrorNumber.EISCONN: return "Unknown error";
1541-
case PythonErrorNumber.EISDIR: return "Is a directory";
1542-
case PythonErrorNumber.EMFILE: return "Too many open files";
1543-
case PythonErrorNumber.EMLINK: return "Too many links";
1544-
case PythonErrorNumber.ENAMETOOLONG: return "Filename too long";
1545-
case PythonErrorNumber.ENFILE: return "Too many open files in system";
1546-
case PythonErrorNumber.ENODEV: return "No such device";
1547-
case PythonErrorNumber.ENOENT: return "No such file or directory";
1548-
case PythonErrorNumber.ENOEXEC: return "Exec format error";
1549-
case PythonErrorNumber.ENOLCK: return "No locks available";
1550-
case PythonErrorNumber.ENOMEM: return "Not enough space";
1551-
case PythonErrorNumber.ENOSPC: return "No space left on device";
1552-
case PythonErrorNumber.ENOSYS: return "Function not implemented";
1553-
case PythonErrorNumber.ENOTDIR: return "Not a directory";
1554-
case PythonErrorNumber.ENOTEMPTY: return "Directory not empty";
1555-
case PythonErrorNumber.ENOTSOCK: return "Unknown error";
1556-
case PythonErrorNumber.ENOTTY: return "Inappropriate I/O control operation";
1557-
case PythonErrorNumber.ENXIO: return "No such device or address";
1558-
case PythonErrorNumber.EPERM: return "Operation not permitted";
1559-
case PythonErrorNumber.EPIPE: return "Broken pipe";
1560-
case PythonErrorNumber.ERANGE: return "Result too large";
1561-
case PythonErrorNumber.EROFS: return "Read-only file system";
1562-
case PythonErrorNumber.ESPIPE: return "Invalid seek";
1563-
case PythonErrorNumber.ESRCH: return "No such process";
1564-
case PythonErrorNumber.EXDEV: return "Improper link";
1565-
default:
1566-
return "Unknown error " + code;
1524+
#if FEATURE_NATIVE
1525+
const int bufsize = 0x1FF;
1526+
var buffer = new StringBuilder(bufsize);
1527+
1528+
int result = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
1529+
Interop.Ucrtbase.strerror(code, buffer) :
1530+
strerror_r(code, buffer);
1531+
1532+
if (result == 0) {
1533+
var msg = buffer.ToString();
1534+
if (msg.Length > 0) {
1535+
return msg;
1536+
}
15671537
}
1538+
#endif
1539+
return "Unknown error " + code;
15681540
}
15691541

1542+
#if FEATURE_NATIVE
1543+
// Isolate Mono.Unix from the rest of the method so that we don't try to load the Mono.Unix assembly on Windows.
1544+
private static int strerror_r(int code, StringBuilder buffer)
1545+
=> Mono.Unix.Native.Syscall.strerror_r(Mono.Unix.Native.NativeConvert.ToErrno(code), buffer);
1546+
#endif
1547+
15701548
#if FEATURE_PROCESS
15711549
[Documentation("system(command) -> int\nExecute the command (a string) in a subshell.")]
15721550
public static int system([NotNone] string command) {
@@ -1854,7 +1832,7 @@ public static PythonTuple waitpid(int pid, int options) {
18541832
Process? process;
18551833
lock (_processToIdMapping) {
18561834
if (!_processToIdMapping.TryGetValue(pid, out process)) {
1857-
throw PythonOps.OSError(PythonErrorNumber.ECHILD, "No child processes");
1835+
throw GetOsError(PythonErrorNumber.ECHILD);
18581836
}
18591837
}
18601838

@@ -2238,15 +2216,13 @@ private static Exception DirectoryExists() {
22382216
#if FEATURE_NATIVE
22392217

22402218
private static Exception GetLastUnixError(string? filename = null, string? filename2 = null)
2241-
=> GetUnixError((int)Mono.Unix.Native.Syscall.GetLastError(), filename, filename2);
2242-
2243-
private static Exception GetUnixError(int error, string? filename = null, string? filename2 = null) {
2244-
var msg = Mono.Unix.Native.Stdlib.strerror((Mono.Unix.Native.Errno)error);
2245-
return PythonOps.OSError(error, msg, filename, null, filename2);
2246-
}
2219+
=> GetOsError(Mono.Unix.Native.NativeConvert.FromErrno(Mono.Unix.Native.Syscall.GetLastError()), filename, filename2);
22472220

22482221
#endif
22492222

2223+
private static Exception GetOsError(int error, string? filename = null, string? filename2 = null)
2224+
=> PythonOps.OSError(error, strerror(error), filename, null, filename2);
2225+
22502226
#if FEATURE_NATIVE || FEATURE_CTYPES
22512227

22522228
// Gets an error message for a Win32 error code.

0 commit comments

Comments
 (0)