Skip to content

Commit ca4a3a7

Browse files
authored
Enable test_shutil (#1157)
* Enable test_shutil * Disable test_shutil on posix
1 parent 7ae32b1 commit ca4a3a7

3 files changed

Lines changed: 36 additions & 16 deletions

File tree

Src/IronPython.Modules/nt.cs

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
using Microsoft.Scripting;
2424
using Microsoft.Scripting.Runtime;
25+
using Microsoft.Scripting.Utils;
2526

2627
using IronPython.Runtime;
2728
using IronPython.Runtime.Exceptions;
@@ -99,6 +100,12 @@ public static void PerformModuleReload([NotNull] PythonContext context, [NotNull
99100

100101
#region Public API Surface
101102

103+
[PythonHidden(PlatformsAttribute.PlatformFamily.Unix)]
104+
public static PythonTuple _getdiskusage([NotNull] string path) {
105+
var driveInfo = new DriveInfo(path);
106+
return PythonTuple.MakeTuple((BigInteger)driveInfo.TotalSize, (BigInteger)driveInfo.AvailableFreeSpace);
107+
}
108+
102109
[DllImport("kernel32.dll", EntryPoint = "GetFinalPathNameByHandleW", CharSet = CharSet.Unicode, SetLastError = true)]
103110
private static extern int GetFinalPathNameByHandle([In] SafeFileHandle hFile, [Out] StringBuilder lpszFilePath, [In] int cchFilePath, [In] int dwFlags);
104111

@@ -508,6 +515,12 @@ static void linkUnix(string src, string dst) {
508515
}
509516
}
510517

518+
public static bool isatty(CodeContext context, int fd) {
519+
if (context.LanguageContext.FileManager.TryGetFileFromId(context.LanguageContext, fd, out var file))
520+
return file.isatty(context);
521+
return false;
522+
}
523+
511524
[Documentation("")]
512525
public static void link([NotNull] Bytes src, [NotNull] Bytes dst, [ParamDictionary, NotNull] IDictionary<string, object> kwargs)
513526
=> link(src.ToFsString(), dst.ToFsString(), kwargs);
@@ -941,10 +954,18 @@ public static void rename([NotNull] string src, [NotNull] string dst, [ParamDict
941954
}
942955
}
943956

944-
try {
945-
Directory.Move(src, dst);
946-
} catch (Exception e) {
947-
throw ToPythonException(e);
957+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
958+
if (!MoveFileEx(src, dst, 0)) {
959+
throw GetLastWin32Error(src, dst);
960+
}
961+
} else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) {
962+
renameUnix(src, dst);
963+
} else {
964+
try {
965+
Directory.Move(src, dst);
966+
} catch (Exception e) {
967+
throw ToPythonException(e);
968+
}
948969
}
949970
}
950971

@@ -961,7 +982,7 @@ public static void rename(CodeContext context, object? src, object? dst, [ParamD
961982
[DllImport("kernel32.dll", EntryPoint = "MoveFileExW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)]
962983
private static extern bool MoveFileEx(string src, string dst, uint flags);
963984

964-
private static void replaceUnix(string src, string dst) {
985+
private static void renameUnix(string src, string dst) {
965986
if (Mono.Unix.Native.Syscall.rename(src, dst) == 0) return;
966987
throw GetLastUnixError(src, dst);
967988
}
@@ -984,7 +1005,7 @@ public static void replace([NotNull] string src, [NotNull] string dst, [ParamDic
9841005
throw GetLastWin32Error(src, dst);
9851006
}
9861007
} else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) {
987-
replaceUnix(src, dst);
1008+
renameUnix(src, dst);
9881009
} else {
9891010
throw new NotImplementedException();
9901011
}
@@ -1208,17 +1229,19 @@ public sealed class stat_result : PythonTuple {
12081229

12091230
private const long nanosecondsPerSeconds = 1_000_000_000;
12101231

1232+
private static object ToInt(BigInteger x) => x.AsInt32(out int i) ? i : (object)x;
1233+
12111234
internal stat_result(int mode) : this(new object[10] { mode, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, null) { }
12121235

12131236
internal stat_result(Mono.Unix.Native.Stat stat)
1214-
: this(new object[16] {(int)stat.st_mode, stat.st_ino, stat.st_dev, stat.st_nlink, stat.st_uid, stat.st_gid, stat.st_size, stat.st_atime, stat.st_mtime, stat.st_ctime,
1237+
: 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),
12151238
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,
1216-
stat.st_atime * nanosecondsPerSeconds + stat.st_atime_nsec, stat.st_mtime * nanosecondsPerSeconds + stat.st_mtime_nsec, stat.st_ctime * nanosecondsPerSeconds + stat.st_ctime_nsec }, null) { }
1239+
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) { }
12171240

12181241
internal stat_result(int mode, ulong fileidx, long size, long st_atime_ns, long st_mtime_ns, long st_ctime_ns)
1219-
: this(new object[16] { mode, fileidx, 0, 0, 0, 0, size, st_atime_ns / nanosecondsPerSeconds, st_mtime_ns / nanosecondsPerSeconds, st_ctime_ns / nanosecondsPerSeconds,
1242+
: 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),
12201243
st_atime_ns / (double)nanosecondsPerSeconds, st_mtime_ns / (double)nanosecondsPerSeconds, st_ctime_ns / (double)nanosecondsPerSeconds,
1221-
st_atime_ns, st_mtime_ns, st_ctime_ns }, null) { }
1244+
ToInt(st_atime_ns), ToInt(st_mtime_ns), ToInt(st_ctime_ns) }, null) { }
12221245

12231246
private stat_result(object?[] statResult, PythonDictionary? dict) : base(statResult.Take(n_sequence_fields).ToArray()) {
12241247
if (statResult.Length < n_sequence_fields) {
@@ -1320,7 +1343,7 @@ public PythonTuple __reduce__() {
13201343

13211344
return MakeTuple(
13221345
DynamicHelpers.GetPythonTypeFromType(typeof(stat_result)),
1323-
MakeTuple(MakeTuple(this), timeDict)
1346+
MakeTuple(new PythonTuple(this), timeDict)
13241347
);
13251348
}
13261349
}

Src/IronPythonTest/Cases/CPythonCasesManifest.ini

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -847,8 +847,7 @@ IsolationLevel=PROCESS # Also weakref failures; https://github.com/IronLanguages
847847
NotParallelSafe=true
848848

849849
[CPython.test_shutil]
850-
Ignore=true
851-
Reason=AttributeError: 'module' object has no attribute 'isatty'
850+
RunCondition=NOT $(IS_POSIX) # TODO: debug
852851

853852
[CPython.test_signal]
854853
Ignore=true

Src/StdLib/Lib/test/test_shutil.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,7 @@ def test_rmtree_works_on_bytes(self):
126126
write_file(os.path.join(victim, 'somefile'), 'foo')
127127
victim = os.fsencode(victim)
128128
self.assertIsInstance(victim, bytes)
129-
win = (os.name == 'nt')
130-
with self.assertWarns(DeprecationWarning) if win else ExitStack():
131-
shutil.rmtree(victim)
129+
shutil.rmtree(victim) # ironpython: deprecation warning check is removed in 3.6 due to https://github.com/IronLanguages/ironpython3/issues/1156
132130

133131
@support.skip_unless_symlink
134132
def test_rmtree_fails_on_symlink(self):

0 commit comments

Comments
 (0)