From 8e0f3df607eb130176298fbc6140a92f4050c333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lozier?= Date: Sat, 4 Jan 2025 10:22:36 -0500 Subject: [PATCH 1/4] Misc changes --- Src/IronPython.Modules/_datetime.cs | 4 +- .../Runtime/Binding/PythonBinder.cs | 47 +++++++++---------- .../Runtime/ClassMethodAttribute.cs | 2 + .../Runtime/ClassMethodDescriptor.cs | 4 +- Src/IronPython/Runtime/CollectionDebugView.cs | 6 +-- .../Runtime/EmptyDictionaryStorage.cs | 23 +++++---- Src/IronPython/Runtime/Index.cs | 9 ++-- Src/Scripts/Install-IronPython.ps1 | 2 +- 8 files changed, 54 insertions(+), 43 deletions(-) diff --git a/Src/IronPython.Modules/_datetime.cs b/Src/IronPython.Modules/_datetime.cs index b3acc4d42..b6e72ce9f 100644 --- a/Src/IronPython.Modules/_datetime.cs +++ b/Src/IronPython.Modules/_datetime.cs @@ -1099,7 +1099,7 @@ internal override int CompareTo(date other) { if (_tz != null) { sb.AppendFormat(", tzinfo={0}", PythonOps.Repr(context, _tz)); } - sb.AppendFormat(")"); + sb.Append(')'); return sb.ToString(); } #endregion @@ -1395,7 +1395,7 @@ private int CompareTo(time other) { sb.AppendFormat(", tzinfo={0}", ltzname.ToLowerInvariant()); } - sb.AppendFormat(")"); + sb.Append(')'); return sb.ToString(); } diff --git a/Src/IronPython/Runtime/Binding/PythonBinder.cs b/Src/IronPython/Runtime/Binding/PythonBinder.cs index 50ae3404b..5b91b531d 100644 --- a/Src/IronPython/Runtime/Binding/PythonBinder.cs +++ b/Src/IronPython/Runtime/Binding/PythonBinder.cs @@ -2,18 +2,21 @@ // The .NET Foundation licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -using System.Linq.Expressions; -using System.Numerics; - using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Dynamic; using System.Linq; +using System.Linq.Expressions; +using System.Numerics; using System.Reflection; using System.Threading; +using IronPython.Runtime.Exceptions; +using IronPython.Runtime.Operations; +using IronPython.Runtime.Types; + using Microsoft.Scripting; using Microsoft.Scripting.Actions; using Microsoft.Scripting.Actions.Calls; @@ -21,10 +24,6 @@ using Microsoft.Scripting.Runtime; using Microsoft.Scripting.Utils; -using IronPython.Runtime.Exceptions; -using IronPython.Runtime.Operations; -using IronPython.Runtime.Types; - namespace IronPython.Runtime.Binding { using Ast = Expression; using AstUtils = Microsoft.Scripting.Ast.Utils; @@ -43,7 +42,7 @@ public PythonBinder(PythonContext/*!*/ pythonContext, CodeContext context) { ContractUtils.RequiresNotNull(pythonContext, nameof(pythonContext)); _dlrExtensionTypes = MakeExtensionTypes(); - _context = pythonContext; + _context = pythonContext; if (context != null) { context.LanguageContext.DomainManager.AssemblyLoaded += new EventHandler(DomainManager_AssemblyLoaded); @@ -82,7 +81,7 @@ public PythonBinder(PythonBinder binder) { } return expr; } - + Type visType = Context.Binder.PrivateBinding ? toType : CompilerHelpers.GetVisibleType(toType); if (exprType == typeof(PythonType) && visType == typeof(Type)) { @@ -185,17 +184,17 @@ public override ErrorInfo MakeSetValueTypeFieldError(FieldTracker field, Dynamic Expression.Assign( Expression.Field( AstUtils.Convert( - instance.Expression, + instance.Expression, field.DeclaringType - ), + ), field.Field ), ConvertExpression( - value.Expression, - field.FieldType, - ConversionResultKind.ExplicitCast, + value.Expression, + field.FieldType, + ConversionResultKind.ExplicitCast, new PythonOverloadResolverFactory( - this, + this, Expression.Constant(_context.SharedContext) ) ) @@ -237,7 +236,7 @@ public override ErrorInfo MakeConversionError(Type toType, Expression value) { return MakeMissingMemberError(accessingType, instance, info.Name); } - public override ErrorInfo/*!*/ MakeStaticPropertyInstanceAccessError(PropertyTracker/*!*/ tracker, bool isAssignment, IList/*!*/ parameters) { + public override ErrorInfo/*!*/ MakeStaticPropertyInstanceAccessError(PropertyTracker/*!*/ tracker, bool isAssignment, IList/*!*/ parameters) { ContractUtils.RequiresNotNull(tracker, nameof(tracker)); ContractUtils.RequiresNotNull(parameters, nameof(parameters)); @@ -281,7 +280,7 @@ public override string GetTypeName(Type t) { } - public override ErrorInfo/*!*/ MakeEventValidation(MemberGroup/*!*/ members, DynamicMetaObject eventObject, DynamicMetaObject/*!*/ value, OverloadResolverFactory/*!*/ factory) { + public override ErrorInfo/*!*/ MakeEventValidation(MemberGroup/*!*/ members, DynamicMetaObject eventObject, DynamicMetaObject/*!*/ value, OverloadResolverFactory/*!*/ factory) { EventTracker ev = (EventTracker)members[0]; return ErrorInfo.FromValueNoError( @@ -405,7 +404,7 @@ public override IList GetExtensionTypes(Type t) { return list; } - + private void AddExtensionTypes(Type t, List list) { ExtensionTypeInfo extType; if (_sysTypes.TryGetValue(t, out extType)) { @@ -461,16 +460,16 @@ private static DynamicMetaObject ReturnMemberTracker(Type type, MemberTracker me case TrackerTypes.Bound: return new DynamicMetaObject(ReturnBoundTracker((BoundMemberTracker)memberTracker, privateBinding), BindingRestrictions.Empty); case TrackerTypes.Property: - return new DynamicMetaObject(ReturnPropertyTracker((PropertyTracker)memberTracker, privateBinding), BindingRestrictions.Empty);; + return new DynamicMetaObject(ReturnPropertyTracker((PropertyTracker)memberTracker, privateBinding), BindingRestrictions.Empty); ; case TrackerTypes.Event: return new DynamicMetaObject(Ast.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.MakeBoundEvent)), AstUtils.Constant(PythonTypeOps.GetReflectedEvent((EventTracker)memberTracker)), AstUtils.Constant(null), AstUtils.Constant(type) - ), BindingRestrictions.Empty);; + ), BindingRestrictions.Empty); case TrackerTypes.Field: - return new DynamicMetaObject(ReturnFieldTracker((FieldTracker)memberTracker), BindingRestrictions.Empty);; + return new DynamicMetaObject(ReturnFieldTracker((FieldTracker)memberTracker), BindingRestrictions.Empty); ; case TrackerTypes.MethodGroup: return new DynamicMetaObject(ReturnMethodGroup((MethodGroup)memberTracker), BindingRestrictions.Empty); ; case TrackerTypes.Constructor: @@ -589,7 +588,7 @@ public void LookupMembers(CodeContext/*!*/ context, PythonType/*!*/ type, Python if (!members.ContainsKey(rm.Name)) { members[rm.Name] = new KeyValuePair( - PythonTypeOps.GetSlot(rm.Member, rm.Name, PrivateBinding), + PythonTypeOps.GetSlot(rm.Member, rm.Name, PrivateBinding), rm.Member ); } @@ -625,7 +624,7 @@ public void ResolveMemberNames(CodeContext/*!*/ context, PythonType/*!*/ type, P if (!members.ContainsKey(rm.Name)) { members[rm.Name] = new KeyValuePair( - PythonTypeOps.GetSlot(rm.Member, rm.Name, PrivateBinding), + PythonTypeOps.GetSlot(rm.Member, rm.Name, PrivateBinding), rm.Member ); } @@ -1084,7 +1083,7 @@ private void EnsureInfo() { private class SlotCacheInfo { public SlotCacheInfo() { Members = new Dictionary>(StringComparer.Ordinal); - } + } public bool TryGetSlot(string/*!*/ name, out PythonTypeSlot slot) { Debug.Assert(name != null); diff --git a/Src/IronPython/Runtime/ClassMethodAttribute.cs b/Src/IronPython/Runtime/ClassMethodAttribute.cs index 02f32648b..59778c6df 100644 --- a/Src/IronPython/Runtime/ClassMethodAttribute.cs +++ b/Src/IronPython/Runtime/ClassMethodAttribute.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. +#nullable enable + using System; namespace IronPython.Runtime { diff --git a/Src/IronPython/Runtime/ClassMethodDescriptor.cs b/Src/IronPython/Runtime/ClassMethodDescriptor.cs index c04c03289..cba36d3b2 100644 --- a/Src/IronPython/Runtime/ClassMethodDescriptor.cs +++ b/Src/IronPython/Runtime/ClassMethodDescriptor.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using IronPython.Runtime.Operations; using IronPython.Runtime.Types; @@ -59,7 +61,7 @@ private PythonType CheckGetArgs(CodeContext context, object instance, PythonType #endregion - public override bool Equals(object obj) { + public override bool Equals(object? obj) { if (!(obj is ClassMethodDescriptor cmd)) return false; return cmd._func == _func; diff --git a/Src/IronPython/Runtime/CollectionDebugView.cs b/Src/IronPython/Runtime/CollectionDebugView.cs index fc070aa21..2369cab1e 100644 --- a/Src/IronPython/Runtime/CollectionDebugView.cs +++ b/Src/IronPython/Runtime/CollectionDebugView.cs @@ -2,11 +2,11 @@ // The .NET Foundation licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -using System; +#nullable enable + +using System.Collections; using System.Collections.Generic; -using System.Text; using System.Diagnostics; -using System.Collections; namespace IronPython.Runtime { internal class CollectionDebugProxy { diff --git a/Src/IronPython/Runtime/EmptyDictionaryStorage.cs b/Src/IronPython/Runtime/EmptyDictionaryStorage.cs index 3e86ff4fa..b9b6ee061 100644 --- a/Src/IronPython/Runtime/EmptyDictionaryStorage.cs +++ b/Src/IronPython/Runtime/EmptyDictionaryStorage.cs @@ -1,6 +1,11 @@ -using System; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +#nullable enable + +using System; using System.Collections.Generic; -using System.Text; using IronPython.Runtime.Operations; @@ -15,7 +20,7 @@ internal class EmptyDictionaryStorage : DictionaryStorage { private EmptyDictionaryStorage() { } - public override void Add(ref DictionaryStorage storage, object key, object value) { + public override void Add(ref DictionaryStorage storage, object? key, object? value) { lock (this) { if (storage == this) { CommonDictionaryStorage newStorage = new CommonDictionaryStorage(); @@ -24,12 +29,12 @@ public override void Add(ref DictionaryStorage storage, object key, object value return; } } - + // race, try again... storage.Add(ref storage, key, value); } - public override bool Remove(ref DictionaryStorage storage, object key) { + public override bool Remove(ref DictionaryStorage storage, object? key) { return false; } @@ -47,7 +52,7 @@ public override DictionaryStorage AsMutable(ref DictionaryStorage storage) { public override void Clear(ref DictionaryStorage storage) { } - public override bool Contains(object key) { + public override bool Contains(object? key) { // make sure argument is valid, do not calculate hash if (PythonContext.IsHashable(key)) { return false; @@ -55,7 +60,7 @@ public override bool Contains(object key) { throw PythonOps.TypeErrorForUnhashableObject(key); } - public override bool TryGetValue(object key, out object value) { + public override bool TryGetValue(object? key, out object? value) { value = null; return false; } @@ -64,8 +69,8 @@ public override int Count { get { return 0; } } - public override List> GetItems() { - return new List>(); + public override List> GetItems() { + return new List>(); } public override DictionaryStorage Clone() { diff --git a/Src/IronPython/Runtime/Index.cs b/Src/IronPython/Runtime/Index.cs index 34efd5270..e6cc4e5ba 100644 --- a/Src/IronPython/Runtime/Index.cs +++ b/Src/IronPython/Runtime/Index.cs @@ -1,6 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Text; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +#nullable enable + using Microsoft.Scripting.Utils; namespace IronPython.Runtime { diff --git a/Src/Scripts/Install-IronPython.ps1 b/Src/Scripts/Install-IronPython.ps1 index 030d93f3f..b549450be 100755 --- a/Src/Scripts/Install-IronPython.ps1 +++ b/Src/Scripts/Install-IronPython.ps1 @@ -46,7 +46,7 @@ Param( [string] $ZipFile, # The moniker of the .NET platform to install for. - [string] $Framework = "net6.0", + [string] $Framework = "net8.0", # If the target path exists, it will be wiped clean beforehand. [switch] $Force From c2ef2a248804aae70715c041b8bf123a84058efb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lozier?= Date: Wed, 26 Oct 2022 16:36:50 -0400 Subject: [PATCH 2/4] Misc bytes change --- Src/IronPython/Runtime/ByteArray.cs | 68 +++++++++---------- Src/IronPython/Runtime/Bytes.cs | 48 +++++++------ Src/IronPython/Runtime/Operations/ByteOps.cs | 18 ++--- .../Runtime/Operations/IListOfByteOps.cs | 14 +--- WhatsNewInPython34.md | 4 +- 5 files changed, 69 insertions(+), 83 deletions(-) diff --git a/Src/IronPython/Runtime/ByteArray.cs b/Src/IronPython/Runtime/ByteArray.cs index 38e54bb6a..613b1400a 100644 --- a/Src/IronPython/Runtime/ByteArray.cs +++ b/Src/IronPython/Runtime/ByteArray.cs @@ -263,7 +263,7 @@ public ByteArray capitalize() { public ByteArray center(int width) => center(width, (byte)' '); public ByteArray center(int width, [BytesLike, NotNone] IList fillchar) - => center(width, fillchar.ToByte("center", 2)); + => center(width, fillchar.ToByte(nameof(center), 2)); private ByteArray center(int width, byte fillchar) { lock (this) { @@ -301,7 +301,7 @@ public int count([BytesLike, NotNone] IList sub, object? start, object? en int istart = start != null ? Converter.ConvertToIndex(start) : 0; lock (this) { int iend = end != null ? Converter.ConvertToIndex(end) : _bytes.Count; - return _bytes.CountOf(sub, istart, iend); + return _bytes.CountOf(sub, istart, iend); } } @@ -585,13 +585,13 @@ public bool isupper() { /// in the sequence seq. The separator between elements is the /// string providing this method /// - public ByteArray join(object? sequence) { - IEnumerator seq = PythonOps.GetEnumerator(sequence); + public ByteArray join(object? iterable) { + IEnumerator seq = PythonOps.GetEnumerator(iterable); if (!seq.MoveNext()) { return new ByteArray(); } - // check if we have just a sequnce of just one value - if so just + // check if we have a sequence of just one value - if so just // return that value. object? curVal = seq.Current; if (!seq.MoveNext()) { @@ -613,34 +613,32 @@ public ByteArray join(object? sequence) { return new ByteArray(ret); } - public ByteArray join([NotNone] PythonList sequence) { - if (sequence.__len__() == 0) { + public ByteArray join([NotNone] PythonList iterable) { + if (iterable.__len__() == 0) { return new ByteArray(); } lock (this) { - if (sequence.__len__() == 1) { - return JoinOne(sequence[0]); + if (iterable.__len__() == 1) { + return JoinOne(iterable[0]); } List ret = new List(); - ByteOps.AppendJoin(sequence._data[0], 0, ret); - for (int i = 1; i < sequence._size; i++) { + ByteOps.AppendJoin(iterable._data[0], 0, ret); + for (int i = 1; i < iterable._size; i++) { ret.AddRange(this); - ByteOps.AppendJoin(sequence._data[i], i, ret); + ByteOps.AppendJoin(iterable._data[i], i, ret); } return new ByteArray(ret); } } - public ByteArray ljust(int width) { - return ljust(width, (byte)' '); - } + public ByteArray ljust(int width) + => ljust(width, (byte)' '); - public ByteArray ljust(int width, [BytesLike, NotNone] IList fillchar) { - return ljust(width, fillchar.ToByte("ljust", 2)); - } + public ByteArray ljust(int width, [BytesLike, NotNone] IList fillchar) + => ljust(width, fillchar.ToByte(nameof(ljust), 2)); private ByteArray ljust(int width, byte fillchar) { lock (this) { @@ -671,7 +669,7 @@ public ByteArray lstrip() { } } - public ByteArray lstrip([BytesLike]IList? chars) { + public ByteArray lstrip([BytesLike] IList? chars) { if (chars == null) return lstrip(); lock (this) { var res = _bytes.LeftStrip(chars); @@ -806,13 +804,11 @@ public int rindex(BigInteger @byte, object? start) public int rindex(BigInteger @byte, object? start, object? end) => rindex(Bytes.FromByte(@byte.ToByteChecked()), start, end); - public ByteArray rjust(int width) { - return rjust(width, (byte)' '); - } + public ByteArray rjust(int width) + => rjust(width, (byte)' '); - public ByteArray rjust(int width, [BytesLike, NotNone] IList fillchar) { - return rjust(width, fillchar.ToByte("rjust", 2)); - } + public ByteArray rjust(int width, [BytesLike, NotNone] IList fillchar) + => rjust(width, fillchar.ToByte(nameof(rjust), 2)); private ByteArray rjust(int width, int fillchar) { byte fill = fillchar.ToByteChecked(); @@ -855,7 +851,7 @@ public PythonTuple rpartition([BytesLike, NotNone] IList sep) { } [return: SequenceTypeInfo(typeof(ByteArray))] - public PythonList rsplit([BytesLike]IList? sep = null, int maxsplit = -1) { + public PythonList rsplit([BytesLike] IList? sep = null, int maxsplit = -1) { lock (this) { return _bytes.RightSplit(sep, maxsplit, x => new ByteArray(new List(x))); } @@ -868,7 +864,7 @@ public ByteArray rstrip() { } } - public ByteArray rstrip([BytesLike]IList? chars) { + public ByteArray rstrip([BytesLike] IList? chars) { if (chars == null) return rstrip(); lock (this) { var res = _bytes.RightStrip(chars); @@ -877,7 +873,7 @@ public ByteArray rstrip([BytesLike]IList? chars) { } [return: SequenceTypeInfo(typeof(ByteArray))] - public PythonList split([BytesLike]IList? sep = null, int maxsplit = -1) { + public PythonList split([BytesLike] IList? sep = null, int maxsplit = -1) { lock (this) { return _bytes.Split(sep, maxsplit, x => new ByteArray(x)); } @@ -973,7 +969,7 @@ public ByteArray strip() { } } - public ByteArray strip([BytesLike]IList? chars) { + public ByteArray strip([BytesLike] IList? chars) { if (chars == null) return strip(); lock (this) { var res = _bytes.Strip(chars); @@ -1000,7 +996,7 @@ private void ValidateTable(IList? table) { } } - public ByteArray translate([BytesLike]IList? table) { + public ByteArray translate([BytesLike] IList? table) { ValidateTable(table); lock (this) { return new ByteArray(_bytes.Translate(table, null)); @@ -1008,14 +1004,14 @@ public ByteArray translate([BytesLike]IList? table) { } - public ByteArray translate([BytesLike]IList? table, [BytesLike, NotNone] IList delete) { + public ByteArray translate([BytesLike] IList? table, [BytesLike, NotNone] IList delete) { ValidateTable(table); lock (this) { return new ByteArray(_bytes.Translate(table, delete)); } } - public ByteArray translate([BytesLike]IList? table, object? delete) { + public ByteArray translate([BytesLike] IList? table, object? delete) { if (delete is IBufferProtocol bufferProtocol) { using var buffer = bufferProtocol.GetBuffer(); return translate(table, buffer.AsReadOnlySpan().ToArray()); @@ -1353,11 +1349,11 @@ private static ByteArray JoinOne(object? curVal) { return new ByteArray(new List(bytes)); } if (curVal is IBufferProtocol bp) { - using (IPythonBuffer buf = bp.GetBuffer()) { - return new ByteArray(new ArrayData(buf.AsReadOnlySpan())); - } + using var buf = bp.GetBufferNoThrow(); + if (buf is null) throw ByteOps.JoinSequenceError(curVal, 0); + return new ByteArray(new ArrayData(buf.AsReadOnlySpan())); } - throw PythonOps.TypeError("can only join an iterable of bytes"); + throw ByteOps.JoinSequenceError(curVal, 0); } private ByteArray CopyThis() { diff --git a/Src/IronPython/Runtime/Bytes.cs b/Src/IronPython/Runtime/Bytes.cs index e6d5ac5d3..3726647d4 100644 --- a/Src/IronPython/Runtime/Bytes.cs +++ b/Src/IronPython/Runtime/Bytes.cs @@ -214,11 +214,11 @@ public Bytes center(int width) => center(width, (byte)' '); public Bytes center(int width, [BytesLike, NotNone] IList fillchar) - => center(width, fillchar.ToByte("center", 2)); + => center(width, fillchar.ToByte(nameof(center), 2)); private Bytes center(int width, byte fillchar) { var res = _bytes.TryCenter(width, fillchar); - return res == null ? this.AsBytes() : new Bytes(res); + return res == null ? AsBytes() : new Bytes(res); } public int count([BytesLike, NotNone] IList sub) @@ -456,8 +456,8 @@ public int index(BigInteger @byte, object? start, object? end) /// in the sequence seq. The separator between elements is the /// string providing this method /// - public Bytes join(object? sequence) { - IEnumerator seq = PythonOps.GetEnumerator(sequence); + public Bytes join(object? iterable) { + IEnumerator seq = PythonOps.GetEnumerator(iterable); if (!seq.MoveNext()) { return Empty; } @@ -484,30 +484,28 @@ public Bytes join(object? sequence) { return new Bytes(ret); } - public Bytes join([NotNone] PythonList sequence) { - if (sequence.__len__() == 0) { + public Bytes join([NotNone] PythonList iterable) { + if (iterable.__len__() == 0) { return Empty; - } else if (sequence.__len__() == 1) { - return JoinOne(sequence[0]); + } else if (iterable.__len__() == 1) { + return JoinOne(iterable[0]); } List ret = new List(); - ByteOps.AppendJoin(sequence._data[0], 0, ret); - for (int i = 1; i < sequence._size; i++) { + ByteOps.AppendJoin(iterable._data[0], 0, ret); + for (int i = 1; i < iterable._size; i++) { ret.AddRange(this); - ByteOps.AppendJoin(sequence._data[i], i, ret); + ByteOps.AppendJoin(iterable._data[i], i, ret); } return new Bytes(ret); } - public Bytes ljust(int width) { - return ljust(width, (byte)' '); - } + public Bytes ljust(int width) + => ljust(width, (byte)' '); - public Bytes ljust(int width, [BytesLike, NotNone] IList fillchar) { - return ljust(width, fillchar.ToByte("ljust", 2)); - } + public Bytes ljust(int width, [BytesLike, NotNone] IList fillchar) + => ljust(width, fillchar.ToByte(nameof(ljust), 2)); private Bytes ljust(int width, byte fillchar) { int spaces = width - Count; @@ -662,13 +660,11 @@ public int rindex(BigInteger @byte, object? start) public int rindex(BigInteger @byte, object? start, object? end) => rindex(Bytes.FromByte(@byte.ToByteChecked()), start, end); - public Bytes rjust(int width) { - return rjust(width, (byte)' '); - } + public Bytes rjust(int width) + => rjust(width, (byte)' '); - public Bytes rjust(int width, [BytesLike, NotNone] IList fillchar) { - return rjust(width, fillchar.ToByte("rjust", 2)); - } + public Bytes rjust(int width, [BytesLike, NotNone] IList fillchar) + => rjust(width, fillchar.ToByte(nameof(rjust), 2)); private Bytes rjust(int width, byte fillchar) { int spaces = width - Count; @@ -1059,9 +1055,11 @@ private static Bytes JoinOne(object? curVal) { return new Bytes(b); } if (curVal is IBufferProtocol bp) { - return new Bytes(bp); + using var buf = bp.GetBufferNoThrow(); + if (buf is null) throw ByteOps.JoinSequenceError(curVal, 0); + return Make(buf.AsReadOnlySpan().ToArray()); } - throw PythonOps.TypeError("can only join an iterable of bytes"); + throw ByteOps.JoinSequenceError(curVal, 0); } internal static Bytes Concat(IList list, int length) { diff --git a/Src/IronPython/Runtime/Operations/ByteOps.cs b/Src/IronPython/Runtime/Operations/ByteOps.cs index 50418728b..e05d866b6 100644 --- a/Src/IronPython/Runtime/Operations/ByteOps.cs +++ b/Src/IronPython/Runtime/Operations/ByteOps.cs @@ -7,11 +7,8 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Linq; using System.Numerics; -using Microsoft.Scripting.Utils; - namespace IronPython.Runtime.Operations { public static partial class ByteOps { internal static byte ToByteChecked(this int item) { @@ -85,12 +82,17 @@ internal static void AppendJoin(object? value, int index, List byteList) { if (value is IList bytesValue) { byteList.AddRange(bytesValue); } else if (value is IBufferProtocol bp) { - using (IPythonBuffer buf = bp.GetBuffer()) { - byteList.AddRange(buf.AsReadOnlySpan().ToArray()); - } - } else { - throw PythonOps.TypeError("sequence item {0}: expected bytes or byte array, {1} found", index.ToString(), PythonOps.GetPythonTypeName(value)); + using var buf = bp.GetBufferNoThrow(); + if (buf is null) throw JoinSequenceError(value, index); + byteList.AddRange(buf.AsReadOnlySpan().ToArray()); } + else { + throw JoinSequenceError(value, index); + } + } + + internal static Exception JoinSequenceError(object? value, int index) { + return PythonOps.TypeError("sequence item {0}: expected a bytes-like object, {1} found", index.ToString(), PythonOps.GetPythonTypeName(value)); } internal static IList CoerceBytes(object? obj) { diff --git a/Src/IronPython/Runtime/Operations/IListOfByteOps.cs b/Src/IronPython/Runtime/Operations/IListOfByteOps.cs index b43e26195..1418bd013 100644 --- a/Src/IronPython/Runtime/Operations/IListOfByteOps.cs +++ b/Src/IronPython/Runtime/Operations/IListOfByteOps.cs @@ -991,19 +991,9 @@ internal static int Find(this IList bytes, IList sub, int start, int return bytes.IndexOf(sub, start, end - start); } - internal static byte ToByte(this string self, string name, int pos) { - if (self.Length != 1 || self[0] >= 256) { - throw PythonOps.TypeError(name + "() argument " + pos + " must be char < 256, not string"); - } - - return (byte)self[0]; - } - internal static byte ToByte(this IList self, string name, int pos) { - if (self == null) { - throw PythonOps.TypeError(name + "() argument " + pos + " must be char < 256, not None"); - } else if (self.Count != 1) { - throw PythonOps.TypeError(name + "() argument " + pos + " must be char < 256, not bytearray or bytes"); + if (self is null || self.Count != 1) { + throw PythonOps.TypeError("{0} () argument {1} must a byte string of length 1, not {2}", name, pos, PythonOps.GetPythonTypeName(self)); } return self[0]; diff --git a/WhatsNewInPython34.md b/WhatsNewInPython34.md index 241983e5a..c3c04ec70 100644 --- a/WhatsNewInPython34.md +++ b/WhatsNewInPython34.md @@ -4,7 +4,7 @@ https://docs.python.org/3/whatsnew/3.4.html PEPs ==== -- [ ] [PEP 453][]: Explicit Bootstrapping of PIP in Python Installations +- [x] [PEP 453][]: Explicit Bootstrapping of PIP in Python Installations - [ ] [PEP 446][]: Newly created file descriptors are non-inheritable - [ ] [PEP 451][]: A `ModuleSpec` Type for the Import System @@ -21,7 +21,7 @@ Other Language Changes - [ ] All the UTF-* codecs (except UTF-7) now reject surrogates during both encoding and decoding unless the surrogatepass error handler is used, with the exception of the UTF-16 decoder and the UTF-16 encoder - [ ] New German EBCDIC codec `cp273`. - [ ] New Ukrainian codec `cp1125`. -- [ ] `bytes.join()` and `bytearray.join()` now accept arbitrary buffer objects as arguments. +- [x] `bytes.join()` and `bytearray.join()` now accept arbitrary buffer objects as arguments. - [ ] The `int` constructor now accepts any object that has an `__index__` method for its base argument. - [ ] Frame objects now have a `clear()` method that clears all references to local variables from the frame. - [ ] `memoryview` is now registered as a `Sequence`, and supports the `reversed()` builtin. From 6b85947b22c8aa74bbbc9b1f8605c6b3481ad985 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lozier?= Date: Mon, 20 Jun 2022 21:20:27 -0400 Subject: [PATCH 3/4] Only create OSError subclass when two args are used --- Src/IronPython/Runtime/Exceptions/PythonExceptions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Src/IronPython/Runtime/Exceptions/PythonExceptions.cs b/Src/IronPython/Runtime/Exceptions/PythonExceptions.cs index 55e97d29b..97dc38f98 100644 --- a/Src/IronPython/Runtime/Exceptions/PythonExceptions.cs +++ b/Src/IronPython/Runtime/Exceptions/PythonExceptions.cs @@ -120,7 +120,7 @@ public override string ToString() { public partial class _OSError { public static new object __new__(PythonType cls, [ParamDictionary] IDictionary kwArgs, params object[] args) { - if (cls == OSError && args.Length >= 1 && args[0] is int errno) { + if (cls == OSError && args.Length >= 2 && args[0] is int errno) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { if (args.Length >= 4 && args[3] is int winerror) { errno = WinErrorToErrno(winerror); @@ -139,8 +139,8 @@ public object filename { set { _filename = value; } } - // TODO: hide property on Unix private object _winerror = Undefined; + [PythonHidden(PlatformsAttribute.PlatformFamily.Unix)] public object winerror { get { return ReferenceEquals(_winerror, Undefined) ? null : _winerror; } set { _winerror = value; } From 1df44603d10390505f1912eb4948fa0144013ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lozier?= Date: Wed, 30 Mar 2022 15:56:54 -0400 Subject: [PATCH 4/4] Enable some test_itertools_stdlib tests --- Src/IronPython.Modules/IterTools.cs | 64 +++++++++++++++-------------- Tests/test_itertools_stdlib.py | 2 - 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/Src/IronPython.Modules/IterTools.cs b/Src/IronPython.Modules/IterTools.cs index e4c0db29c..e9fe0b59f 100644 --- a/Src/IronPython.Modules/IterTools.cs +++ b/Src/IronPython.Modules/IterTools.cs @@ -8,16 +8,16 @@ using System.Numerics; using System.Runtime.InteropServices; -using Microsoft.Scripting; -using Microsoft.Scripting.Runtime; -using Microsoft.Scripting.Utils; - using IronPython.Runtime; using IronPython.Runtime.Binding; using IronPython.Runtime.Exceptions; using IronPython.Runtime.Operations; using IronPython.Runtime.Types; +using Microsoft.Scripting; +using Microsoft.Scripting.Runtime; +using Microsoft.Scripting.Utils; + [assembly: PythonModule("itertools", typeof(IronPython.Modules.PythonIterTools))] namespace IronPython.Modules { public static class PythonIterTools { @@ -233,7 +233,7 @@ private static void EnsureIterator(CodeContext/*!*/ context, object iter) { if (iter == null || !PythonOps.HasAttr(context, iter, "__iter__") && !PythonOps.HasAttr(context, iter, "__getitem__")) { - throw PythonOps.TypeError("'{0}' object is not iterable", PythonOps.GetPythonTypeName(iter)); + throw PythonOps.TypeError("'{0}' object is not iterable", PythonOps.GetPythonTypeName(iter)); } } @@ -276,13 +276,13 @@ public count(BigInteger start) { InnerEnumerator = BigIntYielder(this, start, 1); } - public count(int start=0, int step=1) { + public count(int start = 0, int step = 1) { _curInt = start; _step = step; InnerEnumerator = IntYielder(this, start, step); } - public count([DefaultParameterValue(0)]int start, BigInteger step) { + public count([DefaultParameterValue(0)] int start, BigInteger step) { _curInt = start; _step = step; InnerEnumerator = IntYielder(this, start, step); @@ -300,7 +300,7 @@ public count(BigInteger start, BigInteger step) { InnerEnumerator = BigIntYielder(this, start, step); } - public count(CodeContext/*!*/ context, [DefaultParameterValue(0)]object start, [DefaultParameterValue(1)]object step) { + public count(CodeContext/*!*/ context, [DefaultParameterValue(0)] object start, [DefaultParameterValue(1)] object step) { EnsureNumeric(context, start); EnsureNumeric(context, step); _cur = start; @@ -315,7 +315,7 @@ private static void EnsureNumeric(CodeContext/*!*/ context, object num) { if (num == null || !PythonOps.HasAttr(context, num, "__int__") && !PythonOps.HasAttr(context, num, "__float__")) { - throw PythonOps.TypeError("a number is required"); + throw PythonOps.TypeError("a number is required"); } } @@ -548,9 +548,9 @@ private IEnumerator Yielder(IEnumerator iter) { private IEnumerator Grouper(IEnumerator iter, object curKey) { while (PythonContext.Equal(GetKey(iter.Current), curKey)) { yield return iter.Current; - if (!MoveNextHelper(iter)) { - _fFinished = true; - yield break; + if (!MoveNextHelper(iter)) { + _fFinished = true; + yield break; } } } @@ -675,7 +675,7 @@ public zip_longest(params object[] iterables) { } } - public zip_longest([ParamDictionary]IDictionary paramDict, params object[] iterables) { + public zip_longest([ParamDictionary] IDictionary paramDict, params object[] iterables) { object fill; if (paramDict.TryGetValue("fillvalue", out fill)) { @@ -760,11 +760,14 @@ private static Exception UnexpectedKeywordArgument(IDictionary p [PythonType] public class product : IterBase { + private PythonTuple[] tuples; + public product(CodeContext context, params object[] iterables) { - InnerEnumerator = Yielder(ArrayUtils.ConvertAll(iterables, x => new PythonList(context, PythonOps.GetEnumerator(x)))); + tuples = ArrayUtils.ConvertAll(iterables, x => new PythonTuple(PythonOps.GetEnumerator(x))); + InnerEnumerator = Yielder(tuples); } - public product(CodeContext context, [ParamDictionary]IDictionary paramDict, params object[] iterables) { + public product(CodeContext context, [ParamDictionary] IDictionary paramDict, params object[] iterables) { object repeat; int iRepeat = 1; if (paramDict.TryGetValue("repeat", out repeat)) { @@ -782,21 +785,20 @@ public product(CodeContext context, [ParamDictionary]IDictionary throw UnexpectedKeywordArgument(paramDict); } - PythonList[] finalIterables = new PythonList[iterables.Length * iRepeat]; + tuples = new PythonTuple[iterables.Length * iRepeat]; for (int i = 0; i < iRepeat; i++) { for (int j = 0; j < iterables.Length; j++) { - finalIterables[i * iterables.Length + j] = new PythonList(context, iterables[j]); + tuples[i * iterables.Length + j] = new PythonTuple(iterables[j]); } } - InnerEnumerator = Yielder(finalIterables); + InnerEnumerator = Yielder(tuples); } public PythonTuple __reduce__() { - // TODO return PythonTuple.MakeTuple( DynamicHelpers.GetPythonType(this), - PythonTuple.MakeTuple(), // arguments - null // state + PythonTuple.MakeTuple(tuples), // arguments + null // TODO: state ); } @@ -804,7 +806,7 @@ public void __setstate__(object state) { // TODO } - private IEnumerator Yielder(PythonList[] iterables) { + private IEnumerator Yielder(PythonTuple[] iterables) { if (iterables.Length > 0) { IEnumerator[] enums = new IEnumerator[iterables.Length]; enums[0] = iterables[0].GetEnumerator(); @@ -833,6 +835,7 @@ private IEnumerator Yielder(PythonList[] iterables) { } else { yield return PythonTuple.EMPTY; } + tuples = new PythonTuple[1] { PythonTuple.EMPTY }; } } @@ -987,7 +990,7 @@ public permutations(CodeContext context, object iterable) { public permutations(CodeContext context, object iterable, object r) { _data = new PythonList(context, iterable); - + InnerEnumerator = Yielder(GetR(r, _data)); } @@ -1078,7 +1081,7 @@ public repeat(object @object) { public repeat(object @object, int times) { _obj = @object; InnerEnumerator = Yielder(); - _remaining = times; + _remaining = times < 0 ? 0 : times; } private IEnumerator Yielder() { @@ -1094,10 +1097,9 @@ public int __length_hint__() { } public PythonTuple __reduce__() { - // TODO return PythonTuple.MakeTuple( DynamicHelpers.GetPythonType(this), - PythonTuple.MakeTuple() // arguments + _fInfinite ? PythonTuple.MakeTuple(_obj) : PythonTuple.MakeTuple(_obj, _remaining) // arguments ); } @@ -1150,9 +1152,9 @@ IEnumerator IEnumerable.GetEnumerator() { #endregion } - + [PythonType] - public class starmap : IterBase { + public class starmap : IterBase { public starmap(CodeContext context, object function, object iterable) { InnerEnumerator = Yielder(context, function, PythonOps.GetEnumerator(iterable)); } @@ -1211,7 +1213,7 @@ public void __setstate__(object state) { private IEnumerator Yielder(object predicate, IEnumerator iter) { while (MoveNextHelper(iter)) { - if(!Converter.ConvertToBoolean( + if (!Converter.ConvertToBoolean( _context.LanguageContext.CallSplat(predicate, iter.Current) )) { break; @@ -1222,8 +1224,8 @@ private IEnumerator Yielder(object predicate, IEnumerator iter) { } } - [PythonHidden] - public class TeeIterator : IEnumerator, IWeakReferenceable { + [PythonType("_tee")] + public sealed class TeeIterator : IEnumerator, IWeakReferenceable { internal IEnumerator _iter; internal PythonList _data; private int _curIndex = -1; diff --git a/Tests/test_itertools_stdlib.py b/Tests/test_itertools_stdlib.py index 29d39b65d..4986bb641 100644 --- a/Tests/test_itertools_stdlib.py +++ b/Tests/test_itertools_stdlib.py @@ -26,8 +26,6 @@ def load_tests(loader, standard_tests, pattern): test.test_itertools.TestBasicOps('test_permutations'), # pickling test.test_itertools.TestBasicOps('test_product_issue_25021'), test.test_itertools.TestBasicOps('test_product_pickling'), - test.test_itertools.TestBasicOps('test_repeat'), # pickling - test.test_itertools.TestBasicOps('test_repeat_with_negative_times'), test.test_itertools.TestBasicOps('test_starmap'), # pickling test.test_itertools.TestBasicOps('test_takewhile'), # pickling test.test_itertools.TestBasicOps('test_tee'),