Skip to content

Commit 4eb077e

Browse files
committed
[GR-13716] Make ord() work for any bytes-like
PullRequest: graalpython/556
2 parents 0d8516f + 9aaa278 commit 4eb077e

File tree

3 files changed

+50
-17
lines changed

3 files changed

+50
-17
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_bytes.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,18 @@ def test_endswith():
462462
assert not b.endswith(b"no")
463463

464464

465+
def test_ord():
466+
b = b"123"
467+
assert ord(b[0:1]) == 49
468+
assert ord(bytearray(b)[0:1]) == 49
469+
try:
470+
ord(b)
471+
except TypeError as e:
472+
assert "expected a character" in str(e), str(e)
473+
else:
474+
assert False
475+
476+
465477
def test_find():
466478
b = b'mississippi'
467479
i = 105
@@ -538,7 +550,7 @@ def test_strip_bytes():
538550
assert b'abc'.rstrip(b'ac') == b'ab'
539551

540552
class BaseTestSplit:
541-
553+
542554
def test_string_error(self):
543555
self.assertRaises(TypeError, self.type2test(b'a b').split, ' ')
544556
self.assertRaises(TypeError, self.type2test(b'a b').rsplit, ' ')
@@ -601,10 +613,10 @@ def __init__(self, value):
601613
self.value = value
602614
def __index__(self):
603615
return self.value
604-
616+
605617
self.assertEqual(self.type2test(b'ahoj jak\tse\nmas').split(maxsplit=MyIndexable(1)), [b'ahoj', b'jak\tse\nmas'])
606618
self.assertEqual(self.type2test(b'ahoj jak\tse\nmas').rsplit(maxsplit=MyIndexable(1)), [b'ahoj jak\tse', b'mas'])
607-
619+
608620
class BytesSplitTest(BaseTestSplit, unittest.TestCase):
609621
type2test = bytes
610622

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
import com.oracle.graal.python.builtins.objects.PNotImplemented;
9292
import com.oracle.graal.python.builtins.objects.bytes.BytesNodes;
9393
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
94+
import com.oracle.graal.python.builtins.objects.bytes.PIBytesLike;
9495
import com.oracle.graal.python.builtins.objects.code.PCode;
9596
import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes;
9697
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes;
@@ -1419,15 +1420,30 @@ public int ord(String chr) {
14191420
}
14201421

14211422
@Specialization
1422-
public int ord(PBytes chr,
1423+
public int ord(PIBytesLike chr,
14231424
@Cached("create()") SequenceStorageNodes.LenNode lenNode,
14241425
@Cached("create()") SequenceStorageNodes.GetItemNode getItemNode) {
14251426
int len = lenNode.execute(chr.getSequenceStorage());
14261427
if (len != 1) {
14271428
throw raise(TypeError, "ord() expected a character, but string of length %d found", len);
14281429
}
14291430

1430-
return (byte) getItemNode.execute(chr.getSequenceStorage(), 0);
1431+
Object element = getItemNode.execute(chr.getSequenceStorage(), 0);
1432+
if (element instanceof Long) {
1433+
long e = (long) element;
1434+
if (e >= Byte.MIN_VALUE && e <= Byte.MAX_VALUE) {
1435+
return (int) e;
1436+
}
1437+
} else if (element instanceof Integer) {
1438+
int e = (int) element;
1439+
if (e >= Byte.MIN_VALUE && e <= Byte.MAX_VALUE) {
1440+
return e;
1441+
}
1442+
} else if (element instanceof Byte) {
1443+
return (byte) element;
1444+
}
1445+
CompilerDirectives.transferToInterpreter();
1446+
throw new IllegalStateException("got a bytes-like with non-byte elements");
14311447
}
14321448
}
14331449

mx.graalpython/mx_graalpython.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,21 +1034,26 @@ def python_build_watch(args):
10341034
args = parser.parse_args(args)
10351035
if sum([args.full, args.graalvm, args.no_java]) > 1:
10361036
mx.abort("Only one of --full, --graalvm, --no-java can be specified")
1037+
if args.full:
1038+
suffixes = [".c", ".h", ".class", ".jar", ".java"]
1039+
excludes = [".*\\.py$"]
1040+
elif args.graalvm:
1041+
suffixes = [".c", ".h", ".class", ".jar", ".java", ".py"]
1042+
excludes = ["mx_.*\\.py$"]
1043+
else:
1044+
suffixes = [".c", ".h", ".class", ".jar"]
1045+
excludes = [".*\\.py$", ".*\\.java$"]
1046+
1047+
cmd = ["inotifywait", "-q", "-e", "close_write,moved_to", "-r", "--format=%f"]
1048+
for e in excludes:
1049+
cmd += ["--exclude", e]
1050+
cmd += ["@%s" % os.path.join(SUITE.dir, ".git"), SUITE.dir]
1051+
10371052
while True:
10381053
out = mx.OutputCapture()
1039-
mx.run([
1040-
"inotifywait", "-q", "-e", "close_write,moved_to", "-r", "--format=%f",
1041-
"--exclude", ".*\\.py$",
1042-
"@%s" % os.path.join(SUITE.dir, ".git"),
1043-
SUITE.dir
1044-
], out=out)
1054+
mx.run(cmd, out=out)
10451055
changed_file = out.data.strip()
10461056
mx.logv(changed_file)
1047-
suffixes = [".c", ".h", ".class", ".jar"]
1048-
if args.full:
1049-
suffixes.append(".java")
1050-
elif args.graalvm:
1051-
suffixes.extend([".java", ".py"])
10521057
if any(changed_file.endswith(ext) for ext in [".c", ".h", ".class", ".jar"]):
10531058
mx.log("Build needed ...")
10541059
time.sleep(2)
@@ -1058,7 +1063,7 @@ def python_build_watch(args):
10581063
mx.log(python_gvm())
10591064
else:
10601065
nativebuild([])
1061-
break
1066+
mx.log("Build done.")
10621067

10631068

10641069
# ----------------------------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)