Skip to content

Commit 7abe47d

Browse files
authored
Backport some changes from the 3.6 branch (#1848)
* Backport some changes from the 3.6 branch * Backport more changes * Backport more changes * Fix test failures * Re-enable test on Mono+macOS
1 parent 7a6252b commit 7abe47d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+550
-266
lines changed

Src/IronPython.Modules/IterTools.cs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,23 @@ public PythonTuple __reduce__() {
168168
}
169169

170170
public void __setstate__(PythonTuple state) {
171-
// TODO: error handling?
172-
ie = state[0] as IEnumerator;
173-
inner = (state.Count > 1) ? state[1] as IEnumerator : null;
171+
IEnumerator iter;
172+
IEnumerator innerIter;
173+
switch (state.Count) {
174+
case 0: throw PythonOps.TypeError("function takes at least 1 argument (0 given)");
175+
case 1:
176+
iter = state[0] as IEnumerator ?? throw PythonOps.TypeError("Arguments must be iterators.");
177+
innerIter = null;
178+
break;
179+
case 2:
180+
iter = state[0] as IEnumerator ?? throw PythonOps.TypeError("Arguments must be iterators.");
181+
innerIter = state[1] as IEnumerator ?? throw PythonOps.TypeError("Arguments must be iterators.");
182+
break;
183+
default:
184+
throw PythonOps.TypeError("function takes at most 2 argument ({0} given)", state.Count);
185+
}
186+
ie = iter;
187+
inner = innerIter;
174188
InnerEnumerator = LazyYielder();
175189
}
176190

@@ -515,11 +529,14 @@ public void __setstate__(object state) {
515529
private IEnumerator<object> Yielder(IEnumerator iter) {
516530
object curKey = _starterKey;
517531
if (MoveNextHelper(iter)) {
532+
curKey = GetKey(iter.Current);
533+
yield return PythonTuple.MakeTuple(curKey, Grouper(iter, curKey));
534+
518535
while (!_fFinished) {
519536
while (PythonContext.Equal(GetKey(iter.Current), curKey)) {
520-
if (!MoveNextHelper(iter)) {
521-
_fFinished = true;
522-
yield break;
537+
if (!MoveNextHelper(iter)) {
538+
_fFinished = true;
539+
yield break;
523540
}
524541
}
525542
curKey = GetKey(iter.Current);

Src/IronPython.Modules/_codecs.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,20 @@ public static PythonTuple mbcs_encode(CodeContext/*!*/ context, [NotNone] string
227227

228228
#endregion
229229

230+
#region OEM Functions
231+
232+
[SupportedOSPlatform("windows"), PythonHidden(PlatformsAttribute.PlatformFamily.Unix)]
233+
public static PythonTuple oem_decode(CodeContext/*!*/ context, [NotNone] IBufferProtocol input, string? errors = null, bool final = false) {
234+
using IPythonBuffer buffer = input.GetBuffer();
235+
return DoDecode(context, "oem", StringOps.CodecsInfo.OemEncoding, buffer, errors).ToPythonTuple();
236+
}
237+
238+
[SupportedOSPlatform("windows"), PythonHidden(PlatformsAttribute.PlatformFamily.Unix)]
239+
public static PythonTuple oem_encode(CodeContext/*!*/ context, [NotNone] string input, string? errors = null)
240+
=> DoEncode(context, "oem", StringOps.CodecsInfo.OemEncoding, input, errors).ToPythonTuple();
241+
242+
#endregion
243+
230244
#region Code Page Functions
231245

232246
[SupportedOSPlatform("windows"), PythonHidden(PlatformsAttribute.PlatformFamily.Unix)]

Src/IronPython.Modules/_collections.cs

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -551,20 +551,13 @@ public void __delitem__(CodeContext/*!*/ context, object index) {
551551
}
552552
}
553553

554-
public PythonTuple __reduce__() {
555-
lock (_lockObj) {
556-
object[] items = new object[_itemCnt];
557-
int curItem = 0;
558-
WalkDeque(delegate(int curIndex) {
559-
items[curItem++] = _data[curIndex];
560-
return true;
561-
});
562-
563-
return PythonTuple.MakeTuple(
564-
DynamicHelpers.GetPythonType(this),
565-
PythonTuple.MakeTuple(PythonList.FromArrayNoCopy(items))
566-
);
567-
}
554+
public PythonTuple __reduce__(CodeContext context) {
555+
return PythonTuple.MakeTuple(
556+
DynamicHelpers.GetPythonType(this),
557+
_maxLen == -1 ? PythonTuple.EMPTY : PythonTuple.MakeTuple(PythonTuple.EMPTY, maxlen),
558+
GetType() == typeof(deque) ? null : PythonOps.GetBoundAttr(context, this, "__dict__"),
559+
PythonOps.GetEnumeratorObject(context, this)
560+
);
568561
}
569562

570563
public int __len__() {

Src/IronPython.Modules/_csv.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ public class Dialect {
259259
private Dialect() {
260260
}
261261

262+
[PythonHidden]
262263
public static Dialect Create(CodeContext/*!*/ context,
263264
[ParamDictionary] IDictionary<object, object> kwArgs,
264265
params object[] args) {
@@ -410,6 +411,7 @@ private static string SetString(string name, object src, bool found, string @def
410411
}
411412
return result;
412413
}
414+
413415
#endregion
414416

415417
public Dialect(CodeContext/*!*/ context,
@@ -503,6 +505,13 @@ public Dialect(CodeContext/*!*/ context,
503505
throw PythonOps.TypeError("lineterminator must be set");
504506
}
505507

508+
// CPython defines these overloads on Dialect since 3.10
509+
[Documentation("raises an exception to avoid pickling")]
510+
public object __reduce__(params object[] args) => throw PythonOps.TypeError("cannot pickle 'Dialect' instances");
511+
512+
[Documentation("raises an exception to avoid pickling")]
513+
public object __reduce_ex__(params object[] args) => throw PythonOps.TypeError("cannot pickle 'Dialect' instances");
514+
506515
public string escapechar {
507516
get { return _escapechar; }
508517
}

Src/IronPython.Modules/_ctypes/CFuncPtrType.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ internal static PythonType MakeSystemType(Type underlyingSystemType) {
6969
return PythonType.SetPythonType(underlyingSystemType, new CFuncPtrType(underlyingSystemType));
7070
}
7171

72+
public object from_buffer(object obj)
73+
=> throw PythonOps.TypeError("abstract class");
74+
75+
public object from_buffer_copy(object obj)
76+
=> throw PythonOps.TypeError("abstract class");
77+
7278
/// <summary>
7379
/// Converts an object into a function call parameter.
7480
/// </summary>

Src/IronPython.Modules/_ctypes/NativeArgument.cs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,9 @@
44

55
#if FEATURE_CTYPES
66

7-
using System;
8-
9-
using Microsoft.Scripting.Runtime;
10-
117
using IronPython.Runtime;
128
using IronPython.Runtime.Types;
9+
using IronPython.Runtime.Operations;
1310

1411
namespace IronPython.Modules {
1512
/// <summary>
@@ -35,11 +32,8 @@ public CData _obj {
3532

3633
#region ICodeFormattable Members
3734

38-
public string __repr__(CodeContext context) {
39-
return String.Format("<cparam '{0}' ({1})>",
40-
_type,
41-
IdDispenser.GetId(__obj));// TODO: should be a real address
42-
}
35+
public string __repr__(CodeContext context)
36+
=> $"<cparam '{_type}' ({PythonOps.Repr(context, __obj)})>";
4337

4438
#endregion
4539
}

Src/IronPython.Modules/_ctypes/PointerType.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ private PointerType(Type underlyingSystemType)
4747
: base(underlyingSystemType) {
4848
}
4949

50+
public object from_buffer(object obj)
51+
=> throw PythonOps.TypeError("abstract class");
52+
53+
public object from_buffer_copy(object obj)
54+
=> throw PythonOps.TypeError("abstract class");
55+
5056
public object from_param([NotNone] CData obj) {
5157
return new NativeArgument((CData)PythonCalls.Call(this, obj), "P");
5258
}

Src/IronPython.Modules/_ctypes/_ctypes.cs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -101,27 +101,21 @@ private static IntPtr Cast(IntPtr data, IntPtr obj, IntPtr type) {
101101
GCHandle typeHandle = GCHandle.FromIntPtr(type);
102102
try {
103103
CData cdata = objHandle.Target as CData;
104-
PythonType pt = (PythonType)typeHandle.Target;
104+
PythonType pt = typeHandle.Target as PythonType;
105105

106-
CData res = (CData)pt.CreateInstance(pt.Context.SharedContext);
107-
if (IsPointer(pt)) {
108-
res.MemHolder = new MemoryHolder(IntPtr.Size);
109-
if (IsPointer(DynamicHelpers.GetPythonType(cdata))) {
110-
res.MemHolder.WriteIntPtr(0, cdata.MemHolder.ReadIntPtr(0));
111-
} else {
112-
res.MemHolder.WriteIntPtr(0, data);
113-
}
106+
if (!IsPointer(pt)) throw PythonOps.TypeError("cast() argument 2 must be a pointer type, not {0}", PythonOps.GetPythonTypeName(typeHandle.Target));
114107

115-
if (cdata != null) {
116-
res.MemHolder.Objects = cdata.MemHolder.Objects;
117-
res.MemHolder.AddObject(IdDispenser.GetId(cdata), cdata);
118-
}
108+
CData res = (CData)pt.CreateInstance(pt.Context.SharedContext);
109+
res.MemHolder = new MemoryHolder(IntPtr.Size);
110+
if (IsPointer(DynamicHelpers.GetPythonType(cdata))) {
111+
res.MemHolder.WriteIntPtr(0, cdata.MemHolder.ReadIntPtr(0));
119112
} else {
120-
if (cdata != null) {
121-
res.MemHolder = new MemoryHolder(data, ((INativeType)pt).Size, cdata.MemHolder);
122-
} else {
123-
res.MemHolder = new MemoryHolder(data, ((INativeType)pt).Size);
124-
}
113+
res.MemHolder.WriteIntPtr(0, data);
114+
}
115+
116+
if (cdata != null) {
117+
res.MemHolder.Objects = cdata.MemHolder.Objects;
118+
res.MemHolder.AddObject(IdDispenser.GetId(cdata), cdata);
125119
}
126120

127121
return GCHandle.ToIntPtr(GCHandle.Alloc(res));

Src/IronPython.Modules/_functools.cs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -193,21 +193,33 @@ public void __setstate__(CodeContext context, [NotNone] PythonTuple state) {
193193
}
194194

195195
public string __repr__(CodeContext context) {
196-
var builder = new StringBuilder();
197-
builder.Append("functools.partial(");
198-
builder.Append(PythonOps.Repr(context, func));
199-
foreach (var x in _args) {
200-
builder.Append(", ");
201-
builder.Append(PythonOps.Repr(context, x));
196+
var infinite = PythonOps.GetAndCheckInfinite(this);
197+
if (infinite == null) {
198+
return "...";
202199
}
203-
foreach (var p in _keywordArgs) {
204-
builder.Append(", ");
205-
builder.Append(p.Key);
206-
builder.Append('=');
207-
builder.Append(PythonOps.Repr(context, p.Value));
200+
201+
int infiniteIndex = infinite.Count;
202+
infinite.Add(this);
203+
try {
204+
var builder = new StringBuilder();
205+
builder.Append("functools.partial(");
206+
builder.Append(PythonOps.Repr(context, func));
207+
foreach (var x in _args) {
208+
builder.Append(", ");
209+
builder.Append(PythonOps.Repr(context, x));
210+
}
211+
foreach (var p in _keywordArgs) {
212+
builder.Append(", ");
213+
builder.Append(p.Key);
214+
builder.Append('=');
215+
builder.Append(PythonOps.Repr(context, p.Value));
216+
}
217+
builder.Append(')');
218+
return builder.ToString();
219+
} finally {
220+
System.Diagnostics.Debug.Assert(infiniteIndex == infinite.Count - 1);
221+
infinite.RemoveAt(infiniteIndex);
208222
}
209-
builder.Append(')');
210-
return builder.ToString();
211223
}
212224

213225
#endregion

Src/IronPython.Modules/_heapq.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public static object heapreplace(CodeContext/*!*/ context, PythonList list, obje
7676
}
7777
}
7878

79+
// TODO: removed in Python 3.5
7980
[Documentation("Find the n largest elements in a dataset.\n\n"
8081
+ "Equivalent to: sorted(iterable, reverse=True)[:n]\n"
8182
)]
@@ -108,6 +109,7 @@ public static PythonList nlargest(CodeContext/*!*/ context, int n, object iterab
108109
return ret;
109110
}
110111

112+
// TODO: removed in Python 3.5
111113
[Documentation("Find the n smallest elements in a dataset.\n\n"
112114
+ "Equivalent to: sorted(iterable)[:n]\n"
113115
)]

0 commit comments

Comments
 (0)