mirror of
https://github.com/pocketpy/pocketpy
synced 2026-05-06 18:23:38 +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__register();
|
||||||
py_Type pk_str_iterator__register();
|
py_Type pk_str_iterator__register();
|
||||||
py_Type pk_bytes__register();
|
py_Type pk_bytes__register();
|
||||||
|
py_Type pk_bytes_iterator__register();
|
||||||
py_Type pk_dict__register();
|
py_Type pk_dict__register();
|
||||||
py_Type pk_dict_items__register();
|
py_Type pk_dict_items__register();
|
||||||
py_Type pk_list__register();
|
py_Type pk_list__register();
|
||||||
|
|||||||
@ -840,6 +840,7 @@ enum py_PredefinedType {
|
|||||||
tp_BaseException,
|
tp_BaseException,
|
||||||
tp_Exception,
|
tp_Exception,
|
||||||
tp_bytes,
|
tp_bytes,
|
||||||
|
tp_bytes_iterator,
|
||||||
tp_namedict,
|
tp_namedict,
|
||||||
tp_locals,
|
tp_locals,
|
||||||
tp_code,
|
tp_code,
|
||||||
|
|||||||
@ -674,6 +674,33 @@ py_Type pk_str_iterator__register() {
|
|||||||
return type;
|
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) {
|
static bool bytes__new__(int argc, py_Ref argv) {
|
||||||
if(argc == 1) {
|
if(argc == 1) {
|
||||||
py_newbytes(py_retval(), 0);
|
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, __add__, bytes__add__);
|
||||||
py_bindmagic(tp_bytes, __hash__, bytes__hash__);
|
py_bindmagic(tp_bytes, __hash__, bytes__hash__);
|
||||||
py_bindmagic(tp_bytes, __len__, bytes__len__);
|
py_bindmagic(tp_bytes, __len__, bytes__len__);
|
||||||
|
py_bindmagic(tp_bytes, __iter__, bytes__iter__);
|
||||||
|
|
||||||
py_bindmethod(tp_bytes, "decode", bytes_decode);
|
py_bindmethod(tp_bytes, "decode", bytes_decode);
|
||||||
return type;
|
return type;
|
||||||
|
|||||||
@ -156,6 +156,7 @@ void VM__ctor(VM* self) {
|
|||||||
validate(tp_BaseException, pk_BaseException__register());
|
validate(tp_BaseException, pk_BaseException__register());
|
||||||
validate(tp_Exception, pk_Exception__register());
|
validate(tp_Exception, pk_Exception__register());
|
||||||
validate(tp_bytes, pk_bytes__register());
|
validate(tp_bytes, pk_bytes__register());
|
||||||
|
validate(tp_bytes_iterator, pk_bytes_iterator__register());
|
||||||
validate(tp_namedict, pk_namedict__register());
|
validate(tp_namedict, pk_namedict__register());
|
||||||
validate(tp_locals, pk_newtype("locals", tp_object, NULL, NULL, false, true));
|
validate(tp_locals, pk_newtype("locals", tp_object, NULL, NULL, false, true));
|
||||||
validate(tp_code, pk_code__register());
|
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