Skip to content

Commit 537ac73

Browse files
authored
Re-enable some tests (#1447)
* Re-enable test_minidom * Re-enable test_winsound * Re-enable test_shlex * Re-enable test_pprint * Re-enable test_format * Re-enable test_descrtut * Re-enable test_fractions * Disable test_format on .NET Core 2.1 + Linux * Re-enable test_dictviews
1 parent 3993d5f commit 537ac73

12 files changed

Lines changed: 257 additions & 78 deletions

File tree

Src/IronPython.Modules/winsound.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,20 +120,20 @@ public static void PlaySound(CodeContext/*!*/ context, [NotNone] IBufferProtocol
120120
This parameter must be in the range 37 through 32,767.
121121
The duration argument specifies the number of milliseconds.
122122
")]
123-
public static void Beep(CodeContext/*!*/ context, int freq, int dur) {
124-
if (freq < 37 || freq > 32767) {
123+
public static void Beep(CodeContext/*!*/ context, int frequency, int duration) {
124+
if (frequency < 37 || frequency > 32767) {
125125
throw PythonOps.ValueError("frequency must be in 37 thru 32767");
126126
}
127127

128-
bool ok = Beep(freq, dur);
128+
bool ok = Beep(frequency, duration);
129129
if (!ok) {
130130
throw PythonOps.RuntimeError("Failed to beep");
131131
}
132132
}
133133

134134
[Documentation("MessageBeep(x) - call Windows MessageBeep(x). x defaults to MB_OK.")]
135-
public static void MessageBeep(CodeContext/*!*/ context, int x=MB_OK) {
136-
MessageBeep(x);
135+
public static void MessageBeep(CodeContext/*!*/ context, int type=MB_OK) {
136+
MessageBeep(type);
137137
}
138138

139139
#endregion

Src/IronPython/Runtime/Operations/FloatOps.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,9 @@ static void Warn(CodeContext context, object result) {
115115

116116
public static PythonTuple as_integer_ratio(double self) {
117117
if (Double.IsInfinity(self)) {
118-
throw PythonOps.OverflowError("Cannot pass infinity to float.as_integer_ratio.");
118+
throw PythonOps.OverflowError("cannot convert Infinity to integer ratio");
119119
} else if (Double.IsNaN(self)) {
120-
throw PythonOps.ValueError("Cannot pass nan to float.as_integer_ratio.");
120+
throw PythonOps.ValueError("cannot convert NaN to integer ratio");
121121
}
122122

123123
BigInteger dem = 1;

Src/IronPython/Runtime/Operations/StringOps.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,33 @@ public static string lstrip([NotNone] this string self, string? chars) {
840840
return self.TrimStart(chars.ToCharArray());
841841
}
842842

843+
[StaticExtensionMethod]
844+
public static PythonDictionary maketrans([NotNone] PythonDictionary x) {
845+
var res = new PythonDictionary();
846+
foreach (var p in x) {
847+
object from = p.Key switch {
848+
bool b => ScriptingRuntimeHelpers.Int32ToObject(b ? 1 : 0),
849+
int i => ScriptingRuntimeHelpers.Int32ToObject(i),
850+
BigInteger bi => bi,
851+
Extensible<BigInteger> ebi => ebi.Value,
852+
string s => FromString(s),
853+
Extensible<string> es => FromString(es.Value),
854+
_ => throw PythonOps.TypeError("keys in translate table must be strings or integers"),
855+
};
856+
res[from] = p.Value;
857+
}
858+
return res;
859+
860+
static int FromString(string s) {
861+
// TODO: revisit this once we implement https://github.com/IronLanguages/ironpython3/issues/252
862+
if (s.Length == 1) {
863+
return s[0];
864+
}
865+
866+
throw PythonOps.ValueError("string keys in translate table must be of length 1");
867+
}
868+
}
869+
843870
[StaticExtensionMethod]
844871
public static PythonDictionary maketrans([NotNone] string from, [NotNone] string to) {
845872
if (from.Length != to.Length) throw PythonOps.ValueError("maketrans arguments must have same length");

Src/IronPython/Runtime/PythonDictionary.cs

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,12 @@ internal static PythonDictionary MakeSymbolDictionary(int count) {
8787
return new PythonDictionary(new StringDictionaryStorage(count));
8888
}
8989

90-
public void __init__(CodeContext/*!*/ context, object o\u00F8, [ParamDictionary]IDictionary<object, object> kwArgs) {
90+
public void __init__(CodeContext/*!*/ context, object o\u00F8, [ParamDictionary] IDictionary<object, object> kwArgs) {
9191
update(context, o\u00F8);
9292
update(context, kwArgs);
9393
}
9494

95-
public void __init__(CodeContext/*!*/ context, [ParamDictionary]IDictionary<object, object> kwArgs) {
95+
public void __init__(CodeContext/*!*/ context, [ParamDictionary] IDictionary<object, object> kwArgs) {
9696
update(context, kwArgs);
9797
}
9898

@@ -356,15 +356,15 @@ public object setdefault(object key, object defaultValue) {
356356
public void update() {
357357
}
358358

359-
public void update(CodeContext/*!*/ context, [ParamDictionary]IDictionary<object, object> other\u00F8) {
359+
public void update(CodeContext/*!*/ context, [ParamDictionary] IDictionary<object, object> other\u00F8) {
360360
DictionaryOps.update(context, this, other\u00F8);
361361
}
362362

363363
public void update(CodeContext/*!*/ context, object other\u00F8) {
364364
DictionaryOps.update(context, this, other\u00F8);
365365
}
366366

367-
public void update(CodeContext/*!*/ context, object other\u00F8, [ParamDictionary]IDictionary<object, object> otherArgs\u00F8) {
367+
public void update(CodeContext/*!*/ context, object other\u00F8, [ParamDictionary] IDictionary<object, object> otherArgs\u00F8) {
368368
DictionaryOps.update(context, this, other\u00F8);
369369
DictionaryOps.update(context, this, otherArgs\u00F8);
370370
}
@@ -1046,22 +1046,34 @@ void ICollection.CopyTo(Array array, int index) {
10461046
#region ICodeFormattable Members
10471047

10481048
public string __repr__(CodeContext context) {
1049-
StringBuilder res = new StringBuilder(20);
1050-
res.Append("dict_values([");
1051-
string comma = "";
1052-
foreach (object value in this) {
1053-
res.Append(comma);
1054-
comma = ", ";
1055-
try {
1056-
PythonOps.FunctionPushFrame(context.LanguageContext);
1057-
res.Append(PythonOps.Repr(context, value));
1058-
} finally {
1059-
PythonOps.FunctionPopFrame();
1060-
}
1049+
List<object> infinite = PythonOps.GetAndCheckInfinite(this);
1050+
if (infinite == null) {
1051+
return "...";
10611052
}
1062-
res.Append("])");
10631053

1064-
return res.ToString();
1054+
int index = infinite.Count;
1055+
infinite.Add(this);
1056+
try {
1057+
StringBuilder res = new StringBuilder(20);
1058+
res.Append("dict_values([");
1059+
string comma = "";
1060+
foreach (object value in this) {
1061+
res.Append(comma);
1062+
comma = ", ";
1063+
try {
1064+
PythonOps.FunctionPushFrame(context.LanguageContext);
1065+
res.Append(PythonOps.Repr(context, value));
1066+
} finally {
1067+
PythonOps.FunctionPopFrame();
1068+
}
1069+
}
1070+
res.Append("])");
1071+
1072+
return res.ToString();
1073+
} finally {
1074+
Debug.Assert(index == infinite.Count - 1);
1075+
infinite.RemoveAt(index);
1076+
}
10651077
}
10661078

10671079
#endregion
@@ -1484,7 +1496,7 @@ void ICollection<object>.CopyTo(object[] array, int arrayIndex) {
14841496

14851497
int ICollection<object>.Count => _dict.Count;
14861498

1487-
bool ICollection<object>.IsReadOnly => true;
1499+
bool ICollection<object>.IsReadOnly => true;
14881500

14891501
bool ICollection<object>.Remove(object item) => throw new NotSupportedException("Collection is read-only");
14901502

@@ -1765,22 +1777,34 @@ public override bool Equals(object obj) {
17651777
#region ICodeFormattable Members
17661778

17671779
public string __repr__(CodeContext context) {
1768-
StringBuilder res = new StringBuilder(20);
1769-
res.Append("dict_items([");
1770-
string comma = "";
1771-
foreach (object item in this) {
1772-
res.Append(comma);
1773-
comma = ", ";
1774-
try {
1775-
PythonOps.FunctionPushFrame(context.LanguageContext);
1776-
res.Append(PythonOps.Repr(context, item));
1777-
} finally {
1778-
PythonOps.FunctionPopFrame();
1779-
}
1780+
List<object> infinite = PythonOps.GetAndCheckInfinite(this);
1781+
if (infinite == null) {
1782+
return "...";
17801783
}
1781-
res.Append("])");
17821784

1783-
return res.ToString();
1785+
int index = infinite.Count;
1786+
infinite.Add(this);
1787+
try {
1788+
StringBuilder res = new StringBuilder(20);
1789+
res.Append("dict_items([");
1790+
string comma = "";
1791+
foreach (object item in this) {
1792+
res.Append(comma);
1793+
comma = ", ";
1794+
try {
1795+
PythonOps.FunctionPushFrame(context.LanguageContext);
1796+
res.Append(PythonOps.Repr(context, item));
1797+
} finally {
1798+
PythonOps.FunctionPopFrame();
1799+
}
1800+
}
1801+
res.Append("])");
1802+
1803+
return res.ToString();
1804+
} finally {
1805+
Debug.Assert(index == infinite.Count - 1);
1806+
infinite.RemoveAt(index);
1807+
}
17841808
}
17851809

17861810
#endregion

Src/IronPython/Runtime/StringFormatter.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,9 @@ private void WriteConversion() {
333333
// single character (int or single char str)
334334
case 'c': AppendChar(); return;
335335
// string (repr() version)
336-
case 'r': AppendRepr(); return;
336+
case 'r':
337+
if (_asBytes) goto case 'a';
338+
AppendRepr(); return;
337339
// string (str() version)
338340
case 's':
339341
if (_asBytes) goto case 'b';
@@ -384,9 +386,8 @@ private void WriteConversion() {
384386
}
385387

386388
private object GetIntegerValue(out bool fPos, bool allowDouble = true) {
387-
if (!allowDouble && _opts.Value is float || _opts.Value is double || _opts.Value is Extensible<double>) {
388-
// TODO: this should fail in 3.5
389-
PythonOps.Warn(_context, PythonExceptions.DeprecationWarning, "automatic int conversions have been deprecated");
389+
if (!allowDouble && (_opts.Value is float || _opts.Value is double || _opts.Value is Extensible<double>)) {
390+
throw PythonOps.TypeError($"an integer is required, not {PythonOps.GetPythonTypeName(_opts.Value)}");
390391
}
391392

392393
object val;
@@ -859,10 +860,12 @@ private void AppendBytes() {
859860
Debug.Assert(_asBytes);
860861
if (_opts.Value is Bytes bytes || Bytes.TryInvokeBytesOperator(_context, _opts.Value, out bytes!)) {
861862
AppendString(StringOps.Latin1Encoding.GetString(bytes.UnsafeByteArray));
862-
} else if (_opts.Value is ByteArray byteArray) {
863-
AppendString(StringOps.Latin1Encoding.GetString(byteArray.UnsafeByteList.AsByteSpan()));
863+
} else if (_opts.Value is IBufferProtocol bufferProtocol) {
864+
using var buffer = bufferProtocol.GetBuffer(BufferFlags.FullRO);
865+
var span = buffer.IsCContiguous() ? buffer.AsReadOnlySpan() : buffer.ToArray();
866+
AppendString(StringOps.Latin1Encoding.GetString(span));
864867
} else {
865-
throw PythonOps.TypeError($"%b requires bytes, or an object that implements __bytes__, not '{PythonOps.GetPythonTypeName(_opts.Value)}'");
868+
throw PythonOps.TypeError($"%b requires a bytes-like object, or an object that implements __bytes__, not '{PythonOps.GetPythonTypeName(_opts.Value)}'");
866869
}
867870
}
868871

Src/IronPythonTest/Cases/CPythonCasesManifest.ini

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,9 @@ Ignore=true
458458
Ignore=true
459459
Reason=unittest.case.SkipTest: object <module 'os'> has no attribute 'fork'
460460

461+
[CPython.test_format]
462+
RunCondition=NOT $(IS_NETCOREAPP21) OR NOT $(IS_LINUX) # https://github.com/IronLanguages/ironpython3/issues/751
463+
461464
[CPython.test_frame]
462465
Ignore=true
463466

@@ -620,6 +623,9 @@ IsolationLevel=PROCESS # Also weakref failures; https://github.com/IronLanguages
620623
[CPython.test_metaclass]
621624
Ignore=true
622625

626+
[CPython.test_minidom] # IronPython.test_minidom_stdlib
627+
Ignore=true
628+
623629
[CPython.test_mmap]
624630
RunCondition=NOT $(IS_POSIX)
625631
IsolationLevel=PROCESS
@@ -1191,21 +1197,9 @@ Ignore=true # two failures
11911197
[CPython.test_deque]
11921198
Ignore=true # StackOverflowException
11931199

1194-
[CPython.test_descrtut]
1195-
Ignore=true # single doctest failure
1196-
1197-
[CPython.test_dictviews]
1198-
Ignore=true # test_recursive_repr
1199-
12001200
[CPython.test_fileinput]
12011201
Ignore=true # test_errors
12021202

1203-
[CPython.test_format]
1204-
Ignore=true # two failures
1205-
1206-
[CPython.test_fractions]
1207-
Ignore=true # error message
1208-
12091203
[CPython.test_genericpath]
12101204
Ignore=true # blocked by os.PathLike
12111205

@@ -1239,9 +1233,6 @@ IsolationLevel=PROCESS # https://github.com/IronLanguages/ironpython3/issues/144
12391233
[CPython.test_math]
12401234
Ignore=true # precision?
12411235

1242-
[CPython.test_minidom]
1243-
Ignore=true # testCloneNodeEntity
1244-
12451236
[CPython.test_mmap]
12461237
Ignore=true # 2 failures
12471238

@@ -1252,14 +1243,11 @@ Ignore=true # blocked by os.PathLike
12521243
Ignore=true # __annotations__
12531244

12541245
[CPython.test_ordered_dict]
1255-
Ignore=true # ImportError: Cannot import name Random
1246+
Ignore=true # multiple failures
12561247

12571248
[CPython.test_plistlib]
12581249
Ignore=true # StackOverflowException
12591250

1260-
[CPython.test_pprint]
1261-
Ignore=true # ImportError: Cannot import name Random
1262-
12631251
[CPython.test_print]
12641252
Ignore=true # 7 failures
12651253

@@ -1275,9 +1263,6 @@ Ignore=true # error message changed?
12751263
[CPython.test_set]
12761264
Ignore=true # test_hash_effectiveness
12771265

1278-
[CPython.test_shlex]
1279-
Ignore=true # TypeError: maketrans() takes at least 2 arguments (1 given)
1280-
12811266
[CPython.test_smtpnet]
12821267
Ignore=true # unittest.case.SkipTest: Cannot import name SSLSession
12831268

@@ -1308,8 +1293,5 @@ Ignore=true # LookupError: unknown encoding: oem
13081293
[CPython.test_winreg]
13091294
Ignore=true # 3 failures
13101295

1311-
[CPython.test_winsound]
1312-
Ignore=true # test_keyword_args
1313-
13141296
[CPython.test_zipapp]
13151297
Ignore=true # NotImplementedError: The method or operation is not implemented.

Src/IronPythonTest/Cases/CaseGenerator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ private bool EvaluateExpression(string expression) {
108108
var replacements = new Dictionary<string, string>() {
109109
// variables
110110
{ "$(IS_NETCOREAPP)", IronPython.Runtime.ClrModule.IsNetCoreApp.ToString() },
111+
{ "$(IS_NETCOREAPP21)", (IronPython.Runtime.ClrModule.IsNetCoreApp && IronPython.Runtime.ClrModule.FrameworkDescription.StartsWith(".NET Core 2.", StringComparison.Ordinal)).ToString() },
111112
{ "$(IS_MONO)", IronPython.Runtime.ClrModule.IsMono.ToString() },
112113
{ "$(IS_DEBUG)", IronPython.Runtime.ClrModule.IsDebug.ToString() },
113114
{ "$(IS_POSIX)", (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux)).ToString() },

Src/StdLib/Lib/test/test_descrtut.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ def merge(self, other):
164164
165165
You can get the information from the list type:
166166
167-
Modified to not fail on https://github.com/IronLanguages/ironpython3/issues/995 and https://github.com/IronLanguages/ironpython3/issues/996
167+
Modified to not fail on https://github.com/IronLanguages/ironpython3/issues/995, https://github.com/IronLanguages/ironpython3/issues/996 and https://github.com/IronLanguages/ironpython3/issues/1448
168168
169169
>>> pprint.pprint(dir(list)) # like list.__dict__.keys(), but sorted
170170
['__add__',
@@ -183,7 +183,6 @@ def merge(self, other):
183183
'__iadd__',
184184
'__imul__',
185185
'__init__',
186-
'__init_subclass__',
187186
'__iter__',
188187
'__le__',
189188
'__len__',

Src/StdLib/Lib/test/test_format.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,12 +323,12 @@ def __bytes__(self):
323323
testcommon(b"%s", memoryview(b"abc"), b"abc")
324324
# %a will give the equivalent of
325325
# repr(some_obj).encode('ascii', 'backslashreplace')
326-
testcommon(b"%a", 3.14, b"3.14")
326+
testcommon(b"%a", 3.14, b"3.1400000000000001") # https://github.com/IronLanguages/ironpython2/issues/102
327327
testcommon(b"%a", b"ghi", b"b'ghi'")
328328
testcommon(b"%a", "jkl", b"'jkl'")
329329
testcommon(b"%a", "\u0544", b"'\\u0544'")
330330
# %r is an alias for %a
331-
testcommon(b"%r", 3.14, b"3.14")
331+
testcommon(b"%r", 3.14, b"3.1400000000000001") # https://github.com/IronLanguages/ironpython2/issues/102
332332
testcommon(b"%r", b"ghi", b"b'ghi'")
333333
testcommon(b"%r", "jkl", b"'jkl'")
334334
testcommon(b"%r", "\u0544", b"'\\u0544'")

0 commit comments

Comments
 (0)