Skip to content

Commit b4dc2ac

Browse files
authored
Fixes from 3.6 (#1489)
* Fixes from 3.6 * Fix failing test
1 parent 3e9f91a commit b4dc2ac

5 files changed

Lines changed: 91 additions & 9 deletions

File tree

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: 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/StringFormatter.cs

Lines changed: 3 additions & 1 deletion
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';

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_unicode_stdlib.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def load_tests(loader, standard_tests, pattern):
9595
suite.addTest(test.test_unicode.UnicodeTest('test_literals'))
9696
suite.addTest(test.test_unicode.UnicodeTest('test_ljust'))
9797
suite.addTest(unittest.expectedFailure(test.test_unicode.UnicodeTest('test_lower')))
98-
suite.addTest(unittest.expectedFailure(test.test_unicode.UnicodeTest('test_maketrans_translate')))
98+
suite.addTest(test.test_unicode.UnicodeTest('test_maketrans_translate'))
9999
suite.addTest(unittest.expectedFailure(test.test_unicode.UnicodeTest('test_mul')))
100100
suite.addTest(test.test_unicode.UnicodeTest('test_none_arguments'))
101101
suite.addTest(unittest.expectedFailure(test.test_unicode.UnicodeTest('test_partition')))

0 commit comments

Comments
 (0)