Skip to content

Commit 7726955

Browse files
authored
Reimplement io.StringIO (#1394)
* Reimplement io.StringIO * Cleanup * More cleanup * Fix bug and cleanup
1 parent a8090a0 commit 7726955

5 files changed

Lines changed: 483 additions & 140 deletions

File tree

Src/IronPython/Modules/_io.cs

Lines changed: 14 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1932,103 +1932,6 @@ DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
19321932
#endregion
19331933
}
19341934

1935-
[PythonType]
1936-
public class StringIO : TextIOWrapper, IDynamicMetaObjectProvider {
1937-
public StringIO(
1938-
CodeContext/*!*/ context,
1939-
string initial_value="",
1940-
string newline="\n"
1941-
) : base(context) {
1942-
}
1943-
1944-
private string newline;
1945-
1946-
public void __init__(
1947-
CodeContext/*!*/ context,
1948-
string initial_value="",
1949-
string newline="\n"
1950-
) {
1951-
var buf = new BytesIO(context);
1952-
buf.__init__(null);
1953-
base.__init__(context, buf, "utf-8", null, newline, false);
1954-
1955-
this.newline = newline;
1956-
if (newline == null) {
1957-
_writeTranslate = false;
1958-
}
1959-
if (!string.IsNullOrEmpty(initial_value)) {
1960-
write(context, initial_value);
1961-
seek(context, 0, 0);
1962-
}
1963-
}
1964-
1965-
#region Public API
1966-
1967-
public override object detach(CodeContext/*!*/ context) {
1968-
// doesn't make sense on StringIO
1969-
throw UnsupportedOperation(context, "detach");
1970-
}
1971-
1972-
public string getvalue(CodeContext/*!*/ context) {
1973-
flush(context);
1974-
return ((BytesIO)(object)_bufferTyped).getvalue().decode(context, _encoding, _errors);
1975-
}
1976-
1977-
#endregion
1978-
1979-
#region Pickling
1980-
1981-
public PythonTuple __getstate__(CodeContext context) {
1982-
return PythonTuple.MakeTuple(getvalue(context), newline, tell(context), new PythonDictionary(__dict__));
1983-
}
1984-
1985-
public void __setstate__(CodeContext context, PythonTuple tuple) {
1986-
_checkClosed();
1987-
1988-
if (tuple.__len__() != 4) {
1989-
throw PythonOps.TypeError("_io.StringIO.__setstate__ argument should be 4-tuple, got tuple");
1990-
}
1991-
1992-
var initial_value = tuple[0] as string;
1993-
if (!(tuple[0] is string || tuple[0] is null)) {
1994-
throw PythonOps.TypeError($"initial_value must be str or None, not '{PythonOps.GetPythonTypeName(tuple[0])}'");
1995-
}
1996-
1997-
var newline = tuple[1] as string;
1998-
if (!(tuple[1] is string || tuple[1] is null)) {
1999-
throw PythonOps.TypeError($"newline must be str or None, not '{PythonOps.GetPythonTypeName(tuple[0])}'");
2000-
}
2001-
2002-
if (!(tuple[2] is int i)) {
2003-
throw PythonOps.TypeError($"third item of state must be an integer, not {PythonOps.GetPythonTypeName(tuple[1])}");
2004-
}
2005-
if (i < 0) {
2006-
throw PythonOps.ValueError("position value cannot be negative");
2007-
}
2008-
2009-
var dict = tuple[3] as PythonDictionary;
2010-
if (!(tuple[3] is PythonDictionary || tuple[3] is null)) {
2011-
throw PythonOps.TypeError($"fourth item of state should be a dict, got a {PythonOps.GetPythonTypeName(tuple[2])}");
2012-
}
2013-
2014-
__init__(context, initial_value: initial_value, newline: newline);
2015-
seek(context, i);
2016-
2017-
if (!(dict is null))
2018-
__dict__.update(context, dict);
2019-
}
2020-
2021-
#endregion
2022-
2023-
#region IDynamicMetaObjectProvider Members
2024-
2025-
DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter) {
2026-
return new MetaExpandable<StringIO>(parameter, this);
2027-
}
2028-
2029-
#endregion
2030-
}
2031-
20321935
[PythonType]
20331936
public class TextIOWrapper : _TextIOBase, IEnumerator<object>, IEnumerable<object>, ICodeFormattable, IDynamicMetaObjectProvider {
20341937
public int _CHUNK_SIZE = 128;
@@ -3007,7 +2910,7 @@ internal static TextIOWrapper CreateConsole(PythonContext context, SharedIO io,
30072910
[PythonType]
30082911
public class IncrementalNewlineDecoder {
30092912
[Flags]
3010-
private enum LineEnding {
2913+
internal enum LineEnding {
30112914
None = 0,
30122915
CR = 1,
30132916
LF = 2,
@@ -3153,28 +3056,20 @@ public void reset(CodeContext/*!*/ context) {
31533056
}
31543057
}
31553058

3156-
public object newlines {
3157-
get {
3158-
switch (_seenNL) {
3159-
case LineEnding.None:
3160-
return null;
3161-
case LineEnding.CR:
3162-
return "\r";
3163-
case LineEnding.LF:
3164-
return "\n";
3165-
case LineEnding.CRLF:
3166-
return "\r\n";
3167-
case LineEnding.CR | LineEnding.LF:
3168-
return PythonTuple.MakeTuple("\r", "\n");
3169-
case LineEnding.CR | LineEnding.CRLF:
3170-
return PythonTuple.MakeTuple("\r", "\r\n");
3171-
case LineEnding.LF | LineEnding.CRLF:
3172-
return PythonTuple.MakeTuple("\n", "\r\n");
3173-
default: // LineEnding.All
3174-
return PythonTuple.MakeTuple("\r", "\n", "\r\n");
3175-
}
3176-
}
3059+
internal static object GetNewlines(LineEnding _seenNL) {
3060+
return _seenNL switch {
3061+
LineEnding.None => null,
3062+
LineEnding.CR => "\r",
3063+
LineEnding.LF => "\n",
3064+
LineEnding.CRLF => "\r\n",
3065+
LineEnding.CR | LineEnding.LF => PythonTuple.MakeTuple("\r", "\n"),
3066+
LineEnding.CR | LineEnding.CRLF => PythonTuple.MakeTuple("\r", "\r\n"),
3067+
LineEnding.LF | LineEnding.CRLF => PythonTuple.MakeTuple("\n", "\r\n"),
3068+
_ => PythonTuple.MakeTuple("\r", "\n", "\r\n"), // LineEnding.All
3069+
};
31773070
}
3071+
3072+
public object newlines => GetNewlines(_seenNL);
31783073
}
31793074

31803075
public static PythonType BlockingIOError {

0 commit comments

Comments
 (0)