@@ -133,7 +133,7 @@ public FileIO(CodeContext/*!*/ context, string name, string mode = "r", bool clo
133133 // according to [documentation](https://learn.microsoft.com/en-us/dotnet/api/system.io.filestream.safefilehandle?view=net-9.0#remarks)
134134 // accessing SafeFileHandle sets the current stream position to 0
135135 // in practice it doesn't seem to be the case, but better to be sure
136- if ( this . mode == "ab+" ) {
136+ if ( this . mode . StartsWith ( "ab" , StringComparison . InvariantCulture ) ) {
137137 _streams . WriteStream . Seek ( 0L , SeekOrigin . End ) ;
138138 }
139139 if ( ! _streams . IsSingleStream ) {
@@ -372,26 +372,40 @@ public override BigInteger readinto(CodeContext/*!*/ context, object buf) {
372372 return readinto ( bufferProtocol ) ;
373373 }
374374
375- [ Documentation ( "seek(offset: int[, whence: int]) -> None. Move to new file position.\n \n "
376- + "Argument offset is a byte count. Optional argument whence defaults to\n "
377- + "0 (offset from start of file, offset should be >= 0); other values are 1\n "
378- + "(move relative to current position, positive or negative), and 2 (move\n "
379- + "relative to end of file, usually negative, although many platforms allow\n "
380- + "seeking beyond the end of a file).\n "
381- + "Note that not all file objects are seekable."
382- ) ]
375+
376+ [ Documentation ( """
377+ seek(offset: int[, whence: int]) -> int. Change stream position.
378+
379+ Argument offset is a byte count. Optional argument whence defaults to
380+ 0 or `os.SEEK_SET` (offset from start of file, offset should be >= 0);
381+ other values are 1 or `os.SEEK_CUR` (move relative to current position,
382+ positive or negative), and 2 or `os.SEEK_END` (move relative to end of
383+ file, usually negative, although many platforms allow seeking beyond
384+ the end of a file, by adding zeros to enlarge the file).
385+
386+ Return the new absolute position.
387+
388+ Note that not all file objects are seekable.
389+ """ ) ]
383390 public override BigInteger seek ( CodeContext /*!*/ context , BigInteger offset , [ Optional ] object whence ) {
384391 _checkClosed ( ) ;
385392
386- return _streams . ReadStream . Seek ( ( long ) offset , ( SeekOrigin ) GetInt ( whence ) ) ;
387- }
393+ var origin = ( SeekOrigin ) GetInt ( whence ) ;
394+ if ( origin < SeekOrigin . Begin || origin > SeekOrigin . End )
395+ throw PythonOps . OSError ( PythonFileManager . EINVAL , "Invalid argument" ) ;
388396
389- public BigInteger seek ( double offset , [ Optional ] object whence ) {
390- _checkClosed ( ) ;
397+ long ofs = checked ( ( long ) offset ) ;
398+ if ( ofs < 0 && ClrModule . IsMono && origin == SeekOrigin . Current ) {
399+ // Mono does not support negative offsets with SeekOrigin.Current
400+ // so we need to calculate the absolute offset
401+ ofs += _streams . ReadStream . Position ;
402+ origin = SeekOrigin . Begin ;
403+ }
391404
392- throw PythonOps . TypeError ( "an integer is required" ) ;
405+ return _streams . ReadStream . Seek ( ofs , origin ) ;
393406 }
394407
408+
395409 [ Documentation ( "seekable() -> bool. True if file supports random-access." ) ]
396410 public override bool seekable ( CodeContext /*!*/ context ) {
397411 _checkClosed ( ) ;
0 commit comments