Skip to content

Commit f429410

Browse files
authored
Re-enable some tests (#1469)
* Re-enable test_winreg * Re-enable test_builtin_stdlib * Re-enable test_codeccallbacks_stdlib * Fix failing tests
1 parent 75c7c82 commit f429410

11 files changed

Lines changed: 96 additions & 46 deletions

File tree

Src/IronPython.Modules/winreg.cs

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

55
#if FEATURE_REGISTRY
66

7-
using Microsoft.Win32;
8-
using Microsoft.Win32.SafeHandles;
97
using System;
8+
using System.Buffers.Binary;
109
using System.Collections.Concurrent;
1110
using System.ComponentModel;
1211
using System.Diagnostics;
@@ -22,6 +21,9 @@
2221
using IronPython.Runtime.Exceptions;
2322
using IronPython.Runtime.Types;
2423

24+
using Microsoft.Win32;
25+
using Microsoft.Win32.SafeHandles;
26+
2527
[assembly: PythonModule("winreg", typeof(IronPython.Modules.PythonWinReg), PlatformsAttribute.PlatformFamily.Windows)]
2628
namespace IronPython.Modules {
2729
[SupportedOSPlatform("windows")]
@@ -70,6 +72,7 @@ public static class PythonWinReg {
7072
public const int REG_FULL_RESOURCE_DESCRIPTOR = 0X9;
7173
public const int REG_RESOURCE_REQUIREMENTS_LIST = 0XA;
7274
public const int REG_QWORD = 0xB;
75+
public const int REG_QWORD_LITTLE_ENDIAN = 0XB;
7376

7477
public const int REG_NOTIFY_CHANGE_NAME = 0X1;
7578
public const int REG_NOTIFY_CHANGE_ATTRIBUTES = 0X2;
@@ -346,19 +349,22 @@ private static void QueryValueExImpl(SafeRegistryHandle handle, string valueName
346349
break;
347350
case REG_EXPAND_SZ:
348351
case REG_SZ:
349-
if (length >= 2 && data[length - 1] == 0 && data[length - 2] == 0) {
350-
value = ExtractString(data, 0, (int)length - 2);
351-
} else {
352-
value = ExtractString(data, 0, (int)length);
353-
}
352+
var span = MemoryMarshal.Cast<byte, char>(data.AsSpan());
353+
var len = span.IndexOf((char)0);
354+
if (len != -1) span = span.Slice(0, len);
355+
value = span.ToString();
354356
break;
355357
case REG_DWORD:
356-
if (BitConverter.IsLittleEndian) {
357-
value = (uint)((data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0]);
358-
} else {
359-
value = (uint)((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]);
360-
}
358+
var dval = BitConverter.ToUInt32(data, 0);
359+
if (!BitConverter.IsLittleEndian) dval = BinaryPrimitives.ReverseEndianness(dval);
360+
value = dval > int.MaxValue ? (BigInteger)dval : unchecked((int)dval);
361361
break;
362+
case REG_QWORD:
363+
var qval = BitConverter.ToUInt64(data, 0);
364+
if (!BitConverter.IsLittleEndian) qval = BinaryPrimitives.ReverseEndianness(qval);
365+
value = (BigInteger)qval;
366+
break;
367+
362368
default:
363369
value = null;
364370
break;

Src/IronPython/Modules/Builtin.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public static object __import__(CodeContext/*!*/ context, [NotNone] string name,
5858

5959
object ret = Importer.ImportModule(context, globals, name, from != null && from.Count > 0, level);
6060
if (ret == null) {
61-
var err = PythonOps.ImportError("No module named '{0}'", name);
61+
var err = PythonOps.ModuleNotFoundError("No module named {0}", PythonOps.Repr(context, name));
6262
((PythonExceptions._ImportError)err.GetPythonException()!).name = name;
6363
return LightExceptions.Throw(err);
6464
}

Src/IronPython/Modules/unicodedata.cs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,61 @@ public UCD(string version) {
154154
public string unidata_version { get; private set; }
155155

156156
public string lookup(string name) {
157-
return char.ConvertFromUtf32(nameLookup[name]);
157+
if (TryLookup(name, out int code))
158+
return char.ConvertFromUtf32(code);
159+
throw PythonOps.KeyError("undefined character name");
160+
}
161+
162+
private static bool IsUnifiedIdeograph(int code) {
163+
return (0x3400 <= code && code <= 0x4DB5) || // CJK Ideograph Extension A
164+
(0x4E00 <= code && code <= 0x9FEF) || // CJK Ideograph
165+
(0x20000 <= code && code <= 0x2A6D6) || // CJK Ideograph Extension B
166+
(0x2A700 <= code && code <= 0x2B734) || // CJK Ideograph Extension C - 5.2
167+
(0x2B740 <= code && code <= 0x2B81D) || // CJK Ideograph Extension D - 6.0
168+
(0x2B820 <= code && code <= 0x2CEA1) || // CJK Ideograph Extension E - 8.0
169+
(0x2CEB0 <= code && code <= 0x2EBEF) || // CJK Ideograph Extension F - 10.0
170+
(0x30000 <= code && code <= 0x3134A); // CJK Ideograph Extension G - 13.0
171+
}
172+
173+
private bool TryLookup(string name, out int code) {
174+
code = 0;
175+
176+
if (name.StartsWith("CJK UNIFIED IDEOGRAPH-", StringComparison.Ordinal)) {
177+
var val = name.AsSpan(22);
178+
if (val.Length != 4 && val.Length != 5) return false;
179+
foreach (var c in val) {
180+
code *= 16;
181+
switch (c) {
182+
case '0':
183+
case '1':
184+
case '2':
185+
case '3':
186+
case '4':
187+
case '5':
188+
case '6':
189+
case '7':
190+
case '8':
191+
case '9':
192+
code += c - '0';
193+
break;
194+
case 'A':
195+
case 'B':
196+
case 'C':
197+
case 'D':
198+
case 'E':
199+
case 'F':
200+
code += c - 'A' + 10;
201+
break;
202+
default:
203+
code = 0;
204+
return false;
205+
}
206+
}
207+
return IsUnifiedIdeograph(code);
208+
209+
}
210+
211+
return nameLookup.TryGetValue(name, out code);
158212
}
159213

160214
#nullable enable
@@ -166,6 +220,10 @@ public string name([NotNone] string unichr)
166220
=> TryGetName(GetRune(unichr), out var name) ? name : @default;
167221

168222
internal bool TryGetName(int rune, [NotNullWhen(true)] out string? name) {
223+
if (IsUnifiedIdeograph(rune)) {
224+
name = $"CJK UNIFIED IDEOGRAPH-{rune:X}";
225+
return true;
226+
}
169227
if (TryGetInfo(rune, out CharInfo info, excludeRanges: true)) {
170228
name = info.Name;
171229
return true;

Src/IronPython/Runtime/Operations/StringOps.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,7 @@ private static void AppendValueForTranslate(this StringBuilder ret, object? mapp
12171217
return;
12181218
case int mappedInt:
12191219
if (mappedInt > 0xFFFF) {
1220-
throw PythonOps.TypeError("character mapping must be in range(0x10000)");
1220+
throw PythonOps.ValueError("character mapping must be in range(0x10000)");
12211221
}
12221222
ret.Append((char)mappedInt);
12231223
break;

Src/IronPythonTest/Cases/CPythonCasesManifest.ini

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,7 +1181,7 @@ Ignore=true # blocking
11811181
Ignore=true # https://github.com/IronLanguages/ironpython3/issues/1135
11821182

11831183
[CPython.test_call]
1184-
Ignore=true # test_kwargs_order
1184+
Ignore=true # test_kwargs_order - https://github.com/IronLanguages/ironpython3/issues/1460
11851185

11861186
[CPython.test_code_module]
11871187
Ignore=true # test_context_tb
@@ -1261,8 +1261,5 @@ Ignore=true # test_free_after_iterating
12611261
[CPython.test_uuid]
12621262
Ignore=true # LookupError: unknown encoding: oem - https://github.com/IronLanguages/ironpython3/issues/1451
12631263

1264-
[CPython.test_winreg]
1265-
Ignore=true # 3 failures
1266-
12671264
[CPython.test_zipapp]
12681265
Ignore=true # NotImplementedError: The method or operation is not implemented.

Src/IronPythonTest/Cases/IronPythonCasesManifest.ini

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,6 @@ Ignore=true
180180
[IronPython.modules.system_related.test_signal]
181181
Ignore=true # test_doc
182182

183-
[IronPython.test_builtin_stdlib]
184-
Ignore=true # multiple failures
185-
186-
[IronPython.test_codeccallbacks_stdlib]
187-
Ignore=true # multiple failures
188-
189183
[IronPython.test_imp]
190184
Ignore=true # 1 failure
191185

Tests/test_builtin_stdlib.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,18 @@ def load_tests(loader, standard_tests, pattern):
7979
suite.addTest(unittest.expectedFailure(test.test_builtin.PtyTests('test_input_tty_non_ascii_unicode_errors')))
8080
if not is_netcoreapp:
8181
suite.addTest(test.test_builtin.ShutdownTest('test_cleanup'))
82-
suite.addTest(test.test_builtin.TestSorted('test_bad_arguments'))
82+
suite.addTest(unittest.expectedFailure(test.test_builtin.TestSorted('test_bad_arguments'))) # AssertionError: TypeError not raised
8383
suite.addTest(test.test_builtin.TestSorted('test_baddecorator'))
8484
suite.addTest(test.test_builtin.TestSorted('test_basic'))
8585
suite.addTest(test.test_builtin.TestSorted('test_inputtypes'))
86-
suite.addTest(test.test_builtin.TestType('test_bad_args'))
87-
suite.addTest(test.test_builtin.TestType('test_bad_slots'))
88-
suite.addTest(test.test_builtin.TestType('test_namespace_order'))
89-
suite.addTest(test.test_builtin.TestType('test_new_type'))
90-
suite.addTest(test.test_builtin.TestType('test_type_doc'))
91-
suite.addTest(test.test_builtin.TestType('test_type_name'))
92-
suite.addTest(test.test_builtin.TestType('test_type_nokwargs'))
93-
suite.addTest(test.test_builtin.TestType('test_type_qualname'))
86+
suite.addTest(unittest.expectedFailure(test.test_builtin.TestType('test_bad_args'))) # AssertionError: TypeError not raised
87+
suite.addTest(unittest.expectedFailure(test.test_builtin.TestType('test_bad_slots'))) # AssertionError: TypeError not raised
88+
suite.addTest(unittest.expectedFailure(test.test_builtin.TestType('test_namespace_order'))) # https://github.com/IronLanguages/ironpython3/issues/1468
89+
suite.addTest(unittest.expectedFailure(test.test_builtin.TestType('test_new_type'))) # AssertionError: <class 'test.test_builtin.B'> is not <class 'int'>
90+
suite.addTest(unittest.expectedFailure(test.test_builtin.TestType('test_type_doc'))) # AssertionError: UnicodeEncodeError not raised
91+
suite.addTest(unittest.expectedFailure(test.test_builtin.TestType('test_type_name'))) # AssertionError: ValueError not raised
92+
suite.addTest(unittest.expectedFailure(test.test_builtin.TestType('test_type_nokwargs'))) # AssertionError: TypeError not raised
93+
suite.addTest(unittest.expectedFailure(test.test_builtin.TestType('test_type_qualname'))) # https://github.com/IronLanguages/ironpython3/issues/30
9494
suite.addTest(doctest.DocTestSuite(builtins))
9595
return suite
9696

Tests/test_codeccallbacks_stdlib.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,22 @@
1616
def load_tests(loader, standard_tests, pattern):
1717
if sys.implementation.name == 'ironpython':
1818
suite = unittest.TestSuite()
19-
suite.addTest(unittest.expectedFailure(test.test_codeccallbacks.CodecCallbackTest('test_backslashescape'))) # UTF-16 vs. UTF-32
19+
suite.addTest(test.test_codeccallbacks.CodecCallbackTest('test_backslashescape'))
2020
suite.addTest(unittest.expectedFailure(test.test_codeccallbacks.CodecCallbackTest('test_badandgoodbackslashreplaceexceptions'))) # UTF-16 vs. UTF-32
2121
suite.addTest(test.test_codeccallbacks.CodecCallbackTest('test_badandgoodignoreexceptions'))
22-
suite.addTest(test.test_codeccallbacks.CodecCallbackTest('test_badandgoodnamereplaceexceptions'))
22+
suite.addTest(unittest.expectedFailure(test.test_codeccallbacks.CodecCallbackTest('test_badandgoodnamereplaceexceptions'))) # https://github.com/IronLanguages/ironpython3/issues/252
2323
suite.addTest(unittest.expectedFailure(test.test_codeccallbacks.CodecCallbackTest('test_badandgoodreplaceexceptions'))) # UTF-16 vs. UTF-32
2424
suite.addTest(test.test_codeccallbacks.CodecCallbackTest('test_badandgoodstrictexceptions'))
2525
suite.addTest(test.test_codeccallbacks.CodecCallbackTest('test_badandgoodsurrogateescapeexceptions'))
26-
suite.addTest(test.test_codeccallbacks.CodecCallbackTest('test_badandgoodsurrogatepassexceptions'))
26+
suite.addTest(unittest.expectedFailure(test.test_codeccallbacks.CodecCallbackTest('test_badandgoodsurrogatepassexceptions'))) # AssertionError: UnicodeEncodeError not raised by surrogatepass_errors
2727
suite.addTest(unittest.expectedFailure(test.test_codeccallbacks.CodecCallbackTest('test_badandgoodxmlcharrefreplaceexceptions'))) # UTF-16 vs. UTF-32
2828
suite.addTest(unittest.expectedFailure(test.test_codeccallbacks.CodecCallbackTest('test_badhandlerresults'))) # TypeError not raised by decode
2929
suite.addTest(test.test_codeccallbacks.CodecCallbackTest('test_badlookupcall'))
3030
suite.addTest(test.test_codeccallbacks.CodecCallbackTest('test_badregistercall'))
3131
suite.addTest(test.test_codeccallbacks.CodecCallbackTest('test_bug828737'))
3232
suite.addTest(unittest.expectedFailure(test.test_codeccallbacks.CodecCallbackTest('test_callbacks'))) # Moving cursor not implemented
3333
suite.addTest(test.test_codeccallbacks.CodecCallbackTest('test_charmapencode'))
34-
suite.addTest(test.test_codeccallbacks.CodecCallbackTest('test_crashing_decode_handler'))
34+
suite.addTest(unittest.expectedFailure(test.test_codeccallbacks.CodecCallbackTest('test_crashing_decode_handler'))) # NotImplementedError: Moving a decoding cursor not implemented yet
3535
suite.addTest(unittest.expectedFailure(test.test_codeccallbacks.CodecCallbackTest('test_decodehelper'))) # Moving cursor not implemented
3636
suite.addTest(test.test_codeccallbacks.CodecCallbackTest('test_decodeunicodeinternal'))
3737
suite.addTest(unittest.expectedFailure(test.test_codeccallbacks.CodecCallbackTest('test_decoding_callbacks'))) # Moving cursor not implemented

Tests/test_regressions.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,12 +1103,7 @@ def test_ipy2_gh357(self):
11031103

11041104
import unicodedata
11051105

1106-
if is_cli:
1107-
with self.assertRaises(ValueError):
1108-
unicodedata.name(u'\u4e2d')
1109-
else:
1110-
self.assertEqual(unicodedata.name(u'\u4e2d'), 'CJK UNIFIED IDEOGRAPH-4E2D')
1111-
1106+
self.assertEqual(unicodedata.name(u'\u4e2d'), 'CJK UNIFIED IDEOGRAPH-4E2D')
11121107
self.assertRaises(ValueError, unicodedata.decimal, u'\u4e2d')
11131108
self.assertEqual(unicodedata.decimal(u'\u4e2d', 0), 0)
11141109
self.assertRaises(ValueError, unicodedata.digit, u'\u4e2d')

Tests/test_str.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ def __getitem__(self, idx):
487487
for t in (dict, indexable):
488488
self.assertEqual(u"abcd".translate(t({})), u"abcd")
489489
self.assertEqual(u"abcd".translate(t({ord('a') : ord('A'), ord('b') : None, ord('d') : u"XY"})) , "AcXY")
490-
self.assertRaisesMessage(TypeError, "character mapping must be in range(0x10000)", lambda: 'a'.translate(t({ord('a') : 65536})))
490+
self.assertRaisesMessage(ValueError, "character mapping must be in range(0x10000)", lambda: 'a'.translate(t({ord('a') : sys.maxunicode + 1})))
491491
self.assertRaisesMessage(TypeError, "character mapping must return integer, None or str", lambda: 'a'.translate(t({ord('a') : 2.0})))
492492

493493
class ThrowingIndexable:

0 commit comments

Comments
 (0)