Skip to content

Commit 7c77f2d

Browse files
authored
Fix BytesIO.seek overloads (#593)
* Fix seek overloads * Call proper overload * Change [DefaultParameterValue(0)]object to [Optional]object
1 parent 1d99de8 commit 7c77f2d

4 files changed

Lines changed: 38 additions & 31 deletions

File tree

Src/IronPython.Modules/_bytesio.cs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -253,14 +253,7 @@ public override List readlines([DefaultParameterValue(null)]object hint) {
253253
return lines;
254254
}
255255

256-
[Documentation("seek(pos, whence=0) -> int. Change stream position.\n\n"
257-
+ "Seek to byte offset pos relative to position indicated by whence:\n"
258-
+ " 0 Start of stream (the default). pos should be >= 0;\n"
259-
+ " 1 Current position - pos may be negative;\n"
260-
+ " 2 End of stream - pos usually negative.\n"
261-
+ "Returns the new absolute position."
262-
)]
263-
public BigInteger seek(int pos, int whence = 0) {
256+
private BigInteger seek(int pos, int whence) {
264257
_checkClosed();
265258

266259
switch (whence) {
@@ -281,13 +274,16 @@ public BigInteger seek(int pos, int whence = 0) {
281274
}
282275
}
283276

284-
public BigInteger seek(int pos, BigInteger whence) => seek(pos, (int)whence);
285-
286-
public BigInteger seek(int pos, double whence) => throw PythonOps.TypeError("integer argument expected, got float");
287-
288-
public BigInteger seek(double pos, [DefaultParameterValue(0)]object whence) => throw PythonOps.TypeError("'float' object cannot be interpreted as an index");
277+
public BigInteger seek(double pos, [Optional]object whence) => throw PythonOps.TypeError("'float' object cannot be interpreted as an index");
289278

290-
public override BigInteger seek(CodeContext/*!*/ context, BigInteger pos, [DefaultParameterValue(0)]object whence) {
279+
[Documentation("seek(pos, whence=0) -> int. Change stream position.\n\n"
280+
+ "Seek to byte offset pos relative to position indicated by whence:\n"
281+
+ " 0 Start of stream (the default). pos should be >= 0;\n"
282+
+ " 1 Current position - pos may be negative;\n"
283+
+ " 2 End of stream - pos usually negative.\n"
284+
+ "Returns the new absolute position."
285+
)]
286+
public override BigInteger seek(CodeContext/*!*/ context, BigInteger pos, [Optional]object whence) {
291287
_checkClosed();
292288

293289
int posInt = (int)pos;
@@ -297,9 +293,9 @@ public override BigInteger seek(CodeContext/*!*/ context, BigInteger pos, [Defau
297293
case Extensible<int> v:
298294
return seek(posInt, v);
299295
case BigInteger v:
300-
return seek(posInt, v);
296+
return seek(posInt, (int)v);
301297
case Extensible<BigInteger> v:
302-
return seek(posInt, v);
298+
return seek(posInt, (int)v.Value);
303299
case double _:
304300
case Extensible<double> _:
305301
throw PythonOps.TypeError("integer argument expected, got float");

Src/IronPython.Modules/_fileio.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,13 +361,13 @@ public override BigInteger readinto(CodeContext/*!*/ context, object buf) {
361361
+ "seeking beyond the end of a file).\n"
362362
+ "Note that not all file objects are seekable."
363363
)]
364-
public override BigInteger seek(CodeContext/*!*/ context, BigInteger offset, [DefaultParameterValue(0)]object whence) {
364+
public override BigInteger seek(CodeContext/*!*/ context, BigInteger offset, [Optional]object whence) {
365365
_checkClosed();
366366

367367
return _readStream.Seek((long)offset, (SeekOrigin)GetInt(whence));
368368
}
369369

370-
public BigInteger seek(double offset, [DefaultParameterValue(0)]object whence) {
370+
public BigInteger seek(double offset, [Optional]object whence) {
371371
_checkClosed();
372372

373373
throw PythonOps.TypeError("an integer is required");

Src/IronPython.Modules/_io.cs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
33
// See the LICENSE file in the project root for more information.
4-
using System.Linq.Expressions;
5-
6-
using System.Numerics;
74

85
using System;
96
using System.Collections;
107
using System.Collections.Generic;
118
using System.Diagnostics;
129
using System.Dynamic;
1310
using System.IO;
11+
using System.Linq.Expressions;
12+
using System.Numerics;
13+
using System.Reflection;
1414
using System.Runtime.CompilerServices;
1515
using System.Runtime.InteropServices;
1616
using System.Text;
1717

18-
using Microsoft.Scripting;
1918
using Microsoft.Scripting.Runtime;
2019
using Microsoft.Scripting.Utils;
2120

@@ -241,7 +240,7 @@ public virtual List readlines([DefaultParameterValue(null)]object hint) {
241240
return res;
242241
}
243242

244-
public virtual BigInteger seek(CodeContext/*!*/ context, BigInteger pos, [DefaultParameterValue(0)]object whence) {
243+
public virtual BigInteger seek(CodeContext/*!*/ context, BigInteger pos, [Optional]object whence) {
245244
throw UnsupportedOperation(context, "seek");
246245
}
247246

@@ -911,13 +910,13 @@ public override BigInteger tell(CodeContext/*!*/ context) {
911910
return res - _readBuf.Count + _readBufPos;
912911
}
913912

914-
public BigInteger seek(double offset, [DefaultParameterValue(0)]object whence) {
913+
public BigInteger seek(double offset, [Optional]object whence) {
915914
_checkClosed();
916915

917916
throw PythonOps.TypeError("an integer is required");
918917
}
919918

920-
public override BigInteger seek(CodeContext/*!*/ context, BigInteger pos, [DefaultParameterValue(0)]object whence) {
919+
public override BigInteger seek(CodeContext/*!*/ context, BigInteger pos, [Optional]object whence) {
921920
int whenceInt = GetInt(whence);
922921
if (whenceInt < 0 || whenceInt > 2) {
923922
throw PythonOps.ValueError("invalid whence ({0}, should be 0, 1, or 2)", whenceInt);
@@ -1251,13 +1250,13 @@ public override BigInteger tell(CodeContext/*!*/ context) {
12511250
return res + _writeBuf.Count;
12521251
}
12531252

1254-
public BigInteger seek(double offset, [DefaultParameterValue(0)]object whence) {
1253+
public BigInteger seek(double offset, [Optional]object whence) {
12551254
_checkClosed();
12561255

12571256
throw PythonOps.TypeError("an integer is required");
12581257
}
12591258

1260-
public override BigInteger seek(CodeContext/*!*/ context, BigInteger pos, [DefaultParameterValue(0)]object whence) {
1259+
public override BigInteger seek(CodeContext/*!*/ context, BigInteger pos, [Optional]object whence) {
12611260
int whenceInt = GetInt(whence);
12621261
if (whenceInt < 0 || whenceInt > 2) {
12631262
throw PythonOps.ValueError("invalid whence ({0}, should be 0, 1, or 2)", whenceInt);
@@ -1646,13 +1645,13 @@ public override BigInteger readinto(CodeContext/*!*/ context, object buf) {
16461645
return base.readinto(context, buf);
16471646
}
16481647

1649-
public BigInteger seek(double offset, [DefaultParameterValue(0)]object whence) {
1648+
public BigInteger seek(double offset, [Optional]object whence) {
16501649
_checkClosed();
16511650

16521651
throw PythonOps.TypeError("an integer is required");
16531652
}
16541653

1655-
public override BigInteger seek(CodeContext/*!*/ context, BigInteger pos, [DefaultParameterValue(0)]object whence) {
1654+
public override BigInteger seek(CodeContext/*!*/ context, BigInteger pos, [Optional]object whence) {
16561655
int whenceInt = GetInt(whence);
16571656
if (whenceInt < 0 || whenceInt > 2) {
16581657
throw PythonOps.ValueError("invalid whence ({0}, should be 0, 1, or 2)", whenceInt);
@@ -2289,13 +2288,13 @@ public override object detach(CodeContext/*!*/ context) {
22892288
return res;
22902289
}
22912290

2292-
public BigInteger seek(double offset, [DefaultParameterValue(0)]object whence) {
2291+
public BigInteger seek(double offset, [Optional]object whence) {
22932292
_checkClosed();
22942293

22952294
throw PythonOps.TypeError("an integer is required");
22962295
}
22972296

2298-
public override BigInteger seek(CodeContext/*!*/ context, BigInteger cookie, [DefaultParameterValue(0)]object whence) {
2297+
public override BigInteger seek(CodeContext/*!*/ context, BigInteger cookie, [Optional]object whence) {
22992298
int whenceInt = GetInt(whence);
23002299
if (closed) {
23012300
throw PythonOps.ValueError("tell on closed file");
@@ -3116,6 +3115,8 @@ private static int GetInt(object i, int defaultValue) {
31163115
}
31173116

31183117
private static int GetInt(object i, string msg, params object[] args) {
3118+
if (i == Missing.Value) return 0;
3119+
31193120
int res;
31203121
if (TryGetInt(i, out res)) {
31213122
return res;

Tests/test_regressions.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,4 +1352,14 @@ class test(object):
13521352

13531353
self.assertIs(test().defaultValue, noValue)
13541354

1355+
def test_ipy2_gh546(self):
1356+
"""https://github.com/IronLanguages/ironpython2/issues/546"""
1357+
from io import StringIO
1358+
class Test(StringIO): pass
1359+
Test().seek(0)
1360+
1361+
from io import BytesIO
1362+
class Test(BytesIO): pass
1363+
Test().seek(0)
1364+
13551365
run_test(__name__)

0 commit comments

Comments
 (0)