Skip to content

Commit 5870a46

Browse files
authored
Clean up str/bytes iterator code (#698)
1 parent 0911fb1 commit 5870a46

11 files changed

Lines changed: 197 additions & 182 deletions

Src/IronPython/Runtime/Binding/ConversionBinder.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -450,23 +450,23 @@ public IEnumerable BytesToIEnumerableConversion(CallSite site, Bytes value) {
450450
return ((CallSite<Func<CallSite, Bytes, IEnumerable>>)site).Update(site, value);
451451
}
452452

453-
return PythonOps.BytesIntEnumerable(value);
453+
return PythonOps.BytesEnumerable(value);
454454
}
455455

456456
public IEnumerator BytesToIEnumeratorConversion(CallSite site, Bytes value) {
457457
if (value == null) {
458458
return ((CallSite<Func<CallSite, Bytes, IEnumerator>>)site).Update(site, value);
459459
}
460460

461-
return PythonOps.BytesIntEnumerator(value).Key;
461+
return PythonOps.BytesEnumerator(value).Key;
462462
}
463463

464464
public IEnumerable ObjectToIEnumerableConversion(CallSite site, object value) {
465465
if (value != null) {
466466
if (value is string) {
467467
return PythonOps.StringEnumerable((string)value);
468468
} else if (value.GetType() == typeof(Bytes)) {
469-
return PythonOps.BytesIntEnumerable((Bytes)value);
469+
return PythonOps.BytesEnumerable((Bytes)value);
470470
}
471471
}
472472

@@ -478,7 +478,7 @@ public IEnumerator ObjectToIEnumeratorConversion(CallSite site, object value) {
478478
if (value is string) {
479479
return PythonOps.StringEnumerator((string)value).Key;
480480
} else if (value.GetType() == typeof(Bytes)) {
481-
return PythonOps.BytesIntEnumerator((Bytes)value).Key;
481+
return PythonOps.BytesEnumerator((Bytes)value).Key;
482482
}
483483
}
484484

Src/IronPython/Runtime/Binding/PythonProtocol.Operations.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ private static DynamicMetaObject MakeEnumeratorOperation(PythonOperationBinder o
456456

457457
return new DynamicMetaObject(
458458
Expression.Call(
459-
typeof(PythonOps).GetMethod(nameof(PythonOps.BytesIntEnumerator)),
459+
typeof(PythonOps).GetMethod(nameof(PythonOps.BytesEnumerator)),
460460
self.Expression
461461
),
462462
self.Restrictions

Src/IronPython/Runtime/ByteArray.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1414,7 +1414,7 @@ public bool Remove(byte item) {
14141414
#endregion
14151415

14161416
public IEnumerator __iter__() {
1417-
return PythonOps.BytesIntEnumerator(this).Key;
1417+
return PythonOps.BytesEnumerator(this).Key;
14181418
}
14191419

14201420
#region IEnumerable<byte> Members

Src/IronPython/Runtime/Operations/IListOfByteOps.cs

Lines changed: 3 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,87 +1236,12 @@ internal static byte ToByte(this IList<byte>/*!*/ self, string/*!*/ name, int po
12361236

12371237
#region Conversion and Enumeration
12381238

1239-
[PythonType("bytes_iterator")]
1240-
private class PythonBytesEnumerator<T> : IEnumerable, IEnumerator<T> {
1241-
private readonly IList<byte>/*!*/ _bytes;
1242-
private readonly Func<byte, T>/*!*/ _conversion;
1243-
private int _index;
1244-
1245-
public PythonBytesEnumerator(IList<byte> bytes, Func<byte, T> conversion) {
1246-
Assert.NotNull(bytes);
1247-
Assert.NotNull(conversion);
1248-
1249-
_bytes = bytes;
1250-
_conversion = conversion;
1251-
_index = -1;
1252-
}
1253-
1254-
#region IEnumerator<T> Members
1255-
1256-
public T Current {
1257-
get {
1258-
if (_index < 0) {
1259-
throw PythonOps.SystemError("Enumeration has not started. Call MoveNext.");
1260-
} else if (_index >= _bytes.Count) {
1261-
throw PythonOps.SystemError("Enumeration already finished.");
1262-
}
1263-
return _conversion(_bytes[_index]);
1264-
}
1265-
}
1266-
1267-
#endregion
1268-
1269-
#region IDisposable Members
1270-
1271-
public void Dispose() { }
1272-
1273-
#endregion
1274-
1275-
#region IEnumerator Members
1276-
1277-
object IEnumerator.Current {
1278-
get {
1279-
return ((IEnumerator<T>)this).Current;
1280-
}
1281-
}
1282-
1283-
public bool MoveNext() {
1284-
if (_index >= _bytes.Count) {
1285-
return false;
1286-
}
1287-
_index++;
1288-
return _index != _bytes.Count;
1289-
}
1290-
1291-
public void Reset() {
1292-
_index = -1;
1293-
}
1294-
1295-
#endregion
1296-
1297-
#region IEnumerable Members
1298-
1299-
public IEnumerator GetEnumerator() {
1300-
return this;
1301-
}
1302-
1303-
#endregion
1304-
}
1305-
13061239
internal static IEnumerable BytesEnumerable(IList<byte> bytes) {
1307-
return new PythonBytesEnumerator<Bytes>(bytes, b => Bytes.FromByte(b));
1308-
}
1309-
1310-
internal static IEnumerable BytesIntEnumerable(IList<byte> bytes) {
1311-
return new PythonBytesEnumerator<int>(bytes, b => (int)b);
1312-
}
1313-
1314-
internal static IEnumerator<Bytes> BytesEnumerator(IList<byte> bytes) {
1315-
return new PythonBytesEnumerator<Bytes>(bytes, b => Bytes.FromByte(b));
1240+
return new PythonBytesIterator(bytes);
13161241
}
13171242

1318-
internal static IEnumerator<int> BytesIntEnumerator(IList<byte> bytes) {
1319-
return new PythonBytesEnumerator<int>(bytes, b => (int)b);
1243+
internal static IEnumerator<int> BytesEnumerator(IList<byte> bytes) {
1244+
return new PythonBytesIterator(bytes);
13201245
}
13211246

13221247
#endregion

Src/IronPython/Runtime/Operations/InstanceOps.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ public static object IterMethodForString(string self) {
189189

190190
// 3.0-only
191191
public static object IterMethodForBytes(Bytes self) {
192-
return IListOfByteOps.BytesIntEnumerator(self);
192+
return IListOfByteOps.BytesEnumerator(self);
193193
}
194194

195195
public static object IterMethodForEnumerator(IEnumerator self) {

Src/IronPython/Runtime/Operations/PythonOps.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1940,10 +1940,6 @@ public static KeyValuePair<IEnumerator, IDisposable> BytesEnumerator(IList<byte>
19401940
return new KeyValuePair<IEnumerator, IDisposable>(IListOfByteOps.BytesEnumerator(bytes), null);
19411941
}
19421942

1943-
public static KeyValuePair<IEnumerator, IDisposable> BytesIntEnumerator(IList<byte> bytes) {
1944-
return new KeyValuePair<IEnumerator, IDisposable>(IListOfByteOps.BytesIntEnumerator(bytes), null);
1945-
}
1946-
19471943
public static KeyValuePair<IEnumerator, IDisposable> GetEnumeratorFromEnumerable(IEnumerable enumerable) {
19481944
IEnumerator enumerator = enumerable.GetEnumerator();
19491945
return new KeyValuePair<IEnumerator, IDisposable>(enumerator, enumerator as IDisposable);
@@ -1957,10 +1953,6 @@ public static IEnumerable BytesEnumerable(IList<byte> bytes) {
19571953
return IListOfByteOps.BytesEnumerable(bytes);
19581954
}
19591955

1960-
public static IEnumerable BytesIntEnumerable(IList<byte> bytes) {
1961-
return IListOfByteOps.BytesIntEnumerable(bytes);
1962-
}
1963-
19641956
#region Exception handling
19651957

19661958
// The semantics here are:

Src/IronPython/Runtime/Operations/PythonTypeOps.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -761,10 +761,7 @@ internal static ReflectedGetterSetter GetReflectedProperty(PropertyTracker pt, M
761761
nt = NameType.Property;
762762
}
763763

764-
if (!(pt is ExtensionPropertyTracker ept)) {
765-
ReflectedPropertyTracker rpt = pt as ReflectedPropertyTracker;
766-
Debug.Assert(rpt != null);
767-
764+
if (pt is ReflectedPropertyTracker rpt) {
768765
if (PythonBinder.IsExtendedType(pt.DeclaringType) ||
769766
PythonHiddenAttribute.IsHidden(rpt.Property, true)) {
770767
nt = NameType.Property;
@@ -800,9 +797,10 @@ internal static ReflectedGetterSetter GetReflectedProperty(PropertyTracker pt, M
800797
}
801798
rp = new ReflectedProperty(rpt.Property, getters.ToArray(), setters.ToArray(), nt);
802799
} else {
803-
rp = new ReflectedIndexer(((ReflectedPropertyTracker)pt).Property, NameType.Property, privateBinding);
800+
rp = new ReflectedIndexer(rpt.Property, NameType.Property, privateBinding);
804801
}
805802
} else {
803+
Debug.Assert(pt is ExtensionPropertyTracker);
806804
rp = new ReflectedExtensionProperty(new ExtensionPropertyInfo(pt.DeclaringType, getter ?? setter), nt);
807805
}
808806

Src/IronPython/Runtime/Operations/StringOps.cs

Lines changed: 3 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,7 +1392,7 @@ public static char ConvertToChar(string s) {
13921392
[SpecialName, ImplicitConversionMethod]
13931393
public static IEnumerable ConvertToIEnumerable(string s) {
13941394
// make an enumerator that produces strings instead of chars
1395-
return new PythonStringEnumerable(s);
1395+
return new PythonStrIterator(s);
13961396
}
13971397

13981398
internal static int Compare(string self, string obj) {
@@ -2145,92 +2145,12 @@ private static bool startswith(string self, PythonTuple prefix, int start, int e
21452145
return false;
21462146
}
21472147

2148-
// note: any changes in how this iterator works should also be applied in the
2149-
// optimized overloads of Builtins.map()
2150-
[PythonType("str_iterator")]
2151-
public class PythonStringEnumerable : IEnumerable, IEnumerator<string> {
2152-
private readonly string/*!*/ _s;
2153-
private int _index;
2154-
2155-
public PythonStringEnumerable(string s) {
2156-
Assert.NotNull(s);
2157-
2158-
_index = -1;
2159-
_s = s;
2160-
}
2161-
2162-
public PythonTuple __reduce__(CodeContext/*!*/ context) {
2163-
object iter;
2164-
context.TryLookupBuiltin("iter", out iter);
2165-
return PythonTuple.MakeTuple(
2166-
iter,
2167-
PythonTuple.MakeTuple(_s),
2168-
_index + 1
2169-
);
2170-
}
2171-
2172-
public void __setstate__(int index) {
2173-
_index = index - 1;
2174-
}
2175-
2176-
#region IEnumerable Members
2177-
2178-
public IEnumerator GetEnumerator() {
2179-
return this;
2180-
}
2181-
2182-
#endregion
2183-
2184-
#region IEnumerator<string> Members
2185-
2186-
public string Current {
2187-
get {
2188-
if (_index < 0) {
2189-
throw PythonOps.SystemError("Enumeration has not started. Call MoveNext.");
2190-
} else if (_index >= _s.Length) {
2191-
throw PythonOps.SystemError("Enumeration already finished.");
2192-
}
2193-
return ScriptingRuntimeHelpers.CharToString(_s[_index]);
2194-
}
2195-
}
2196-
2197-
#endregion
2198-
2199-
#region IDisposable Members
2200-
2201-
public void Dispose() { }
2202-
2203-
#endregion
2204-
2205-
#region IEnumerator Members
2206-
2207-
object IEnumerator.Current {
2208-
get {
2209-
return ((IEnumerator<string>)this).Current;
2210-
}
2211-
}
2212-
2213-
public bool MoveNext() {
2214-
if (_index >= _s.Length) {
2215-
return false;
2216-
}
2217-
_index++;
2218-
return _index != _s.Length;
2219-
}
2220-
2221-
public void Reset() {
2222-
_index = -1;
2223-
}
2224-
2225-
#endregion
2226-
}
2227-
22282148
internal static IEnumerable StringEnumerable(string str) {
2229-
return new PythonStringEnumerable(str);
2149+
return new PythonStrIterator(str);
22302150
}
22312151

22322152
internal static IEnumerator<string> StringEnumerator(string str) {
2233-
return new PythonStringEnumerable(str);
2153+
return new PythonStrIterator(str);
22342154
}
22352155

22362156
#endregion
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Collections;
6+
using System.Collections.Generic;
7+
8+
using Microsoft.Scripting.Utils;
9+
10+
using IronPython.Runtime.Operations;
11+
12+
namespace IronPython.Runtime {
13+
[PythonType("bytes_iterator")]
14+
public class PythonBytesIterator : IEnumerable, IEnumerator<int> {
15+
private readonly IList<byte>/*!*/ _bytes;
16+
private int _index;
17+
18+
public PythonBytesIterator(IList<byte> bytes) {
19+
Assert.NotNull(bytes);
20+
21+
_bytes = bytes;
22+
_index = -1;
23+
}
24+
25+
#region IEnumerator<T> Members
26+
27+
[PythonHidden]
28+
public int Current {
29+
get {
30+
if (_index < 0) {
31+
throw PythonOps.SystemError("Enumeration has not started. Call MoveNext.");
32+
} else if (_index >= _bytes.Count) {
33+
throw PythonOps.SystemError("Enumeration already finished.");
34+
}
35+
return _bytes[_index];
36+
}
37+
}
38+
39+
#endregion
40+
41+
#region IDisposable Members
42+
43+
[PythonHidden]
44+
public void Dispose() { }
45+
46+
#endregion
47+
48+
#region IEnumerator Members
49+
50+
object IEnumerator.Current {
51+
get {
52+
return ((IEnumerator<int>)this).Current;
53+
}
54+
}
55+
56+
[PythonHidden]
57+
public bool MoveNext() {
58+
if (_index >= _bytes.Count) {
59+
return false;
60+
}
61+
_index++;
62+
return _index != _bytes.Count;
63+
}
64+
65+
[PythonHidden]
66+
public void Reset() {
67+
_index = -1;
68+
}
69+
70+
#endregion
71+
72+
#region IEnumerable Members
73+
74+
[PythonHidden]
75+
public IEnumerator GetEnumerator() {
76+
return this;
77+
}
78+
79+
#endregion
80+
}
81+
}

Src/IronPython/Runtime/PythonHiddenAttribute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace IronPython.Runtime {
99
/// <summary>
1010
/// Marks a member as being hidden from Python code.
1111
/// </summary>
12-
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
12+
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
1313
public sealed class PythonHiddenAttribute : PlatformsAttribute {
1414
public PythonHiddenAttribute(params PlatformID[] hiddenPlatforms) {
1515
ValidPlatforms = hiddenPlatforms;

0 commit comments

Comments
 (0)