diff --git a/Directory.Build.props b/Directory.Build.props index 2beab9202..afe0e4b4b 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -27,6 +27,8 @@ $(MajorVersion).$(MinorVersion).$(MicroVersion).$(AssemblyFileRevision) $(MSBuildProjectName) $(MajorVersion).$(MinorVersion).$(MicroVersion) $(ReleaseLevel) $(ReleaseSerial) + PYTHON_$(MajorVersion)$(MinorVersion) + false false @@ -125,7 +127,7 @@ portable true false - $(Features);$(SignedSym);TRACE + $(DefineConstants);$(Features);$(SignedSym);TRACE @@ -135,6 +137,6 @@ false false - $(Features);$(SignedSym);DEBUG;TRACE + $(DefineConstants);$(Features);$(SignedSym);DEBUG;TRACE diff --git a/IronPython.sln b/IronPython.sln index 6a760c366..2a77b6b94 100644 --- a/IronPython.sln +++ b/IronPython.sln @@ -42,7 +42,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{17737ACB eng\net9.0-windows.props = eng\net9.0-windows.props eng\net9.0.props = eng\net9.0.props eng\netstandard2.0.props = eng\netstandard2.0.props - eng\steps.yml = eng\steps.yml eng\Tasks.Targets = eng\Tasks.Targets EndProjectSection EndProject diff --git a/src/core/IronPython.Modules/_ctypes/SimpleType.cs b/src/core/IronPython.Modules/_ctypes/SimpleType.cs index 14475cc33..eca813430 100644 --- a/src/core/IronPython.Modules/_ctypes/SimpleType.cs +++ b/src/core/IronPython.Modules/_ctypes/SimpleType.cs @@ -58,8 +58,18 @@ public SimpleType(CodeContext/*!*/ context, string name, PythonTuple bases, Pyth case 'H': _type = SimpleTypeKind.UnsignedShort; break; case 'i': _type = SimpleTypeKind.SignedInt; break; case 'I': _type = SimpleTypeKind.UnsignedInt; break; - case 'l': _type = SimpleTypeKind.SignedLong; break; - case 'L': _type = SimpleTypeKind.UnsignedLong; break; + case 'l': + _type = SimpleTypeKind.SignedLong; +#if !PYTHON_34 + _charType = TypecodeOps.IsCLong32Bit ? _charType : 'q'; +#endif + break; + case 'L': + _type = SimpleTypeKind.UnsignedLong; +#if !PYTHON_34 + _charType = TypecodeOps.IsCLong32Bit ? _charType : 'Q'; +#endif + break; case 'f': _type = SimpleTypeKind.Single; break; case 'g': // long double, new in 2.6 case 'd': _type = SimpleTypeKind.Double; break; diff --git a/src/core/IronPython.Modules/_datetime.cs b/src/core/IronPython.Modules/_datetime.cs index e05d2be26..f657ddd09 100644 --- a/src/core/IronPython.Modules/_datetime.cs +++ b/src/core/IronPython.Modules/_datetime.cs @@ -54,13 +54,15 @@ internal timedelta(TimeSpan ts, double microsecond) } public timedelta(double days, double seconds, double microseconds, double milliseconds, double minutes, double hours, double weeks) { - double totalDays = weeks * 7 + days; - double totalSeconds = ((totalDays * 24 + hours) * 60 + minutes) * 60 + seconds; + double totalSeconds = (((weeks * 7 + days) * 24 + hours) * 60 + minutes) * 60 + seconds; + CheckDouble(totalSeconds); double totalSecondsSharp = Math.Floor(totalSeconds); double totalSecondsFloat = totalSeconds - totalSecondsSharp; double totalMicroseconds = Math.Round(totalSecondsFloat * 1e6 + milliseconds * 1000 + microseconds); + CheckDouble(totalMicroseconds); + double otherSecondsFromMicroseconds = Math.Floor(totalMicroseconds / 1e6); totalSecondsSharp += otherSecondsFromMicroseconds; @@ -71,28 +73,45 @@ public timedelta(double days, double seconds, double microseconds, double millis totalMicroseconds += 1e6; } - _days = (int)(totalSecondsSharp / SECONDSPERDAY); - _seconds = (int)(totalSecondsSharp - _days * SECONDSPERDAY); + _days = ToInt(totalSecondsSharp / SECONDSPERDAY); + _seconds = ToInt(totalSecondsSharp - _days * SECONDSPERDAY); if (_seconds < 0) { _days--; _seconds += (int)SECONDSPERDAY; } - _microseconds = (int)(totalMicroseconds); + _microseconds = ToInt(totalMicroseconds); if (Math.Abs(_days) > MAXDAYS) { throw PythonOps.OverflowError("days={0}; must have magnitude <= 999999999", _days); } + + static void CheckDouble(double d) { + if (double.IsInfinity(d)) { + throw PythonOps.OverflowError("cannot convert float infinity to integer"); + } else if (double.IsNaN(d)) { + throw PythonOps.ValueError("cannot convert float NaN to integer"); + } + } + + static int ToInt(double d) { + if (Int32.MinValue <= d && d <= Int32.MaxValue) { + return (int)d; + } else { + CheckDouble(d); + return checked((int)d); + } + } } public static timedelta __new__(CodeContext context, [NotNone] PythonType cls, - double days = 0D, - double seconds = 0D, - double microseconds = 0D, - double milliseconds = 0D, - double minutes = 0D, - double hours = 0D, - double weeks = 0D) { + double days = 0, + double seconds = 0, + double microseconds = 0, + double milliseconds = 0, + double minutes = 0, + double hours = 0, + double weeks = 0) { if (cls == DynamicHelpers.GetPythonTypeFromType(typeof(timedelta))) { return new timedelta(days, seconds, microseconds, milliseconds, minutes, hours, weeks); } else { @@ -1218,7 +1237,7 @@ public PythonTuple __reduce__() { ); } - // TODO: get rid of __bool__ in 3.5 +#if PYTHON_34 public bool __bool__() { return this.UtcTime.TimeSpan.Ticks != 0 || this.UtcTime.LostMicroseconds != 0; } @@ -1226,6 +1245,7 @@ public bool __bool__() { public static explicit operator bool([NotNone] time time) { return time.__bool__(); } +#endif // instance methods public object replace() { diff --git a/src/core/IronPython.Modules/mmap.cs b/src/core/IronPython.Modules/mmap.cs index 94c31e3a5..a02f82ba2 100644 --- a/src/core/IronPython.Modules/mmap.cs +++ b/src/core/IronPython.Modules/mmap.cs @@ -338,6 +338,10 @@ public MmapDefault(CodeContext/*!*/ context, int fileno, long length, string? ta _offset = 0; // offset is ignored without an underlying file _sourceStream = null; + if (length == 0) { + throw PythonNT.GetOsError(PythonErrno.EINVAL); + } + // work around the .NET bug whereby CreateOrOpen throws on a null mapName if (_mapName is null) { _file = MemoryMappedFile.CreateNew(null, length, _fileAccess); @@ -859,7 +863,7 @@ public Bytes read(int len) { len = checked((int)(_view.Capacity - pos)); } - if (len == 0) { + if (len <= 0) { return Bytes.Empty; } @@ -960,11 +964,6 @@ public void resize(long newsize) { } } - if (_sourceStream == null) { - // resizing is not supported without an underlying file - throw WindowsError(PythonExceptions._OSError.ERROR_INVALID_PARAMETER); - } - if (_view.Capacity == newsize) { // resizing to the same size return; @@ -979,6 +978,33 @@ public void resize(long newsize) { ); } + if (_sourceStream is null) { + // resizing of anonymous map + // TODO: non-copying implementation? + + MemoryMappedFile file; + // work around the .NET bug whereby CreateOrOpen throws on a null mapName + if (_mapName is null) { + file = MemoryMappedFile.CreateNew(null, newsize, _fileAccess); + } else { + Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + file = MemoryMappedFile.CreateOrOpen(_mapName, newsize, _fileAccess); + } + + using (var oldStream = _file.CreateViewStream(0, Math.Min(_view.Capacity, newsize))) { + using var newStream = file.CreateViewStream(); + oldStream.CopyTo(newStream); + } + + _view.Flush(); + _view.Dispose(); + _file.Dispose(); + + _file = file; + _view = _file.CreateViewAccessor(_offset, newsize, _fileAccess); + return; + } + _view.Flush(); _view.Dispose(); _file.Dispose(); diff --git a/src/core/IronPython.Modules/nt.cs b/src/core/IronPython.Modules/nt.cs index ea48bc5e1..7d6d9c20b 100644 --- a/src/core/IronPython.Modules/nt.cs +++ b/src/core/IronPython.Modules/nt.cs @@ -849,6 +849,8 @@ public static object open(CodeContext/*!*/ context, [NotNone] string path, int f } } + VerifyPath(path, functionName: nameof(open), argName: nameof(path)); + if ((RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) && !ClrModule.IsMono) { // Use PosixFileStream to operate on fd directly // On Mono, we must use FileStream due to limitations in MemoryMappedFile