mirror of
https://github.com/pocketpy/pocketpy
synced 2026-05-06 10:13:37 +00:00
fix(bytes): make bytes object iterable - fixes #450
This commit is contained in:
parent
9a57b281e8
commit
4de7a16af4
@ -133,6 +133,7 @@ void pk_number__register();
|
||||
py_Type pk_str__register();
|
||||
py_Type pk_str_iterator__register();
|
||||
py_Type pk_bytes__register();
|
||||
py_Type pk_bytes_iterator__register();
|
||||
py_Type pk_dict__register();
|
||||
py_Type pk_dict_items__register();
|
||||
py_Type pk_list__register();
|
||||
|
||||
@ -840,6 +840,7 @@ enum py_PredefinedType {
|
||||
tp_BaseException,
|
||||
tp_Exception,
|
||||
tp_bytes,
|
||||
tp_bytes_iterator,
|
||||
tp_namedict,
|
||||
tp_locals,
|
||||
tp_code,
|
||||
|
||||
@ -674,6 +674,33 @@ py_Type pk_str_iterator__register() {
|
||||
return type;
|
||||
}
|
||||
|
||||
static bool bytes__iter__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
int* ud = py_newobject(py_retval(), tp_bytes_iterator, 1, sizeof(int));
|
||||
*ud = 0;
|
||||
py_setslot(py_retval(), 0, argv); // keep a reference to the bytes object
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bytes_iterator__next__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
int* ud = py_touserdata(&argv[0]);
|
||||
int size;
|
||||
unsigned char* data = py_tobytes(py_getslot(argv, 0), &size);
|
||||
if(*ud == size) return StopIteration();
|
||||
py_newint(py_retval(), data[*ud]); // return the byte value as an integer (0-255)
|
||||
*ud += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
py_Type pk_bytes_iterator__register() {
|
||||
py_Type type = pk_newtype("bytes_iterator", tp_object, NULL, NULL, false, true);
|
||||
|
||||
py_bindmagic(type, __iter__, pk_wrapper__self);
|
||||
py_bindmagic(type, __next__, bytes_iterator__next__);
|
||||
return type;
|
||||
}
|
||||
|
||||
static bool bytes__new__(int argc, py_Ref argv) {
|
||||
if(argc == 1) {
|
||||
py_newbytes(py_retval(), 0);
|
||||
@ -808,6 +835,7 @@ py_Type pk_bytes__register() {
|
||||
py_bindmagic(tp_bytes, __add__, bytes__add__);
|
||||
py_bindmagic(tp_bytes, __hash__, bytes__hash__);
|
||||
py_bindmagic(tp_bytes, __len__, bytes__len__);
|
||||
py_bindmagic(tp_bytes, __iter__, bytes__iter__);
|
||||
|
||||
py_bindmethod(tp_bytes, "decode", bytes_decode);
|
||||
return type;
|
||||
|
||||
@ -156,6 +156,7 @@ void VM__ctor(VM* self) {
|
||||
validate(tp_BaseException, pk_BaseException__register());
|
||||
validate(tp_Exception, pk_Exception__register());
|
||||
validate(tp_bytes, pk_bytes__register());
|
||||
validate(tp_bytes_iterator, pk_bytes_iterator__register());
|
||||
validate(tp_namedict, pk_namedict__register());
|
||||
validate(tp_locals, pk_newtype("locals", tp_object, NULL, NULL, false, true));
|
||||
validate(tp_code, pk_code__register());
|
||||
|
||||
76
test_bytes_iter.py
Normal file
76
test_bytes_iter.py
Normal file
@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python3
|
||||
# Test script for bytes iteration fix (issue #450)
|
||||
|
||||
print("Testing bytes iteration...")
|
||||
print()
|
||||
|
||||
# Test 1: Basic bytes creation and representation
|
||||
text = "Hello"
|
||||
byte_data = text.encode()
|
||||
print("Test 1: Basic bytes creation and representation")
|
||||
print(f"Text: {text}")
|
||||
print(f"Bytes: {byte_data}")
|
||||
print()
|
||||
|
||||
# Test 2: list(bytes)
|
||||
print("Test 2: list(byte_data):")
|
||||
try:
|
||||
result = list(byte_data)
|
||||
print(f"Result: {result}")
|
||||
expected = [72, 101, 108, 108, 111]
|
||||
assert result == expected, f"Expected {expected}, got {result}"
|
||||
print("✓ PASS")
|
||||
except Exception as e:
|
||||
print(f"✗ FAIL: {e}")
|
||||
print()
|
||||
|
||||
# Test 3: for loop iteration
|
||||
print("Test 3: for loop iteration")
|
||||
try:
|
||||
result = []
|
||||
for x in byte_data:
|
||||
result.append(x)
|
||||
print(f"Result: {result}")
|
||||
expected = [72, 101, 108, 108, 111]
|
||||
assert result == expected, f"Expected {expected}, got {result}"
|
||||
print("✓ PASS")
|
||||
except Exception as e:
|
||||
print(f"✗ FAIL: {e}")
|
||||
print()
|
||||
|
||||
# Test 4: bytes indexing (should still work)
|
||||
print("Test 4: bytes indexing")
|
||||
try:
|
||||
result = byte_data[0]
|
||||
print(f"byte_data[0] = {result}")
|
||||
assert result == 72, f"Expected 72, got {result}"
|
||||
print("✓ PASS")
|
||||
except Exception as e:
|
||||
print(f"✗ FAIL: {e}")
|
||||
print()
|
||||
|
||||
# Test 5: len(bytes)
|
||||
print("Test 5: len(byte_data)")
|
||||
try:
|
||||
result = len(byte_data)
|
||||
print(f"len(byte_data) = {result}")
|
||||
assert result == 5, f"Expected 5, got {result}"
|
||||
print("✓ PASS")
|
||||
except Exception as e:
|
||||
print(f"✗ FAIL: {e}")
|
||||
print()
|
||||
|
||||
# Test 6: bytes slicing
|
||||
print("Test 6: bytes slicing")
|
||||
try:
|
||||
result = byte_data[1:3]
|
||||
result_list = list(result)
|
||||
print(f"list(byte_data[1:3]) = {result_list}")
|
||||
expected = [101, 108]
|
||||
assert result_list == expected, f"Expected {expected}, got {result_list}"
|
||||
print("✓ PASS")
|
||||
except Exception as e:
|
||||
print(f"✗ FAIL: {e}")
|
||||
print()
|
||||
|
||||
print("All tests completed!")
|
||||
Loading…
x
Reference in New Issue
Block a user