Skip to content

Commit d625bd9

Browse files
committed
Implement bytes() constructor
1 parent f72f347 commit d625bd9

File tree

1 file changed

+103
-1
lines changed

1 file changed

+103
-1
lines changed

‎py/bytes.go‎

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,113 @@
22

33
package py
44

5-
varBytesType=NewType("bytes", "bytes(iterable_of_ints) -> bytes\nbytes(string, encoding[, errors]) -> bytes\nbytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer\nbytes(int) -> bytes object of size given by the parameter initialized with null bytes\nbytes() -> empty bytes object\n\nConstruct an immutable array of bytes from:\n - an iterable yielding integers in range(256)\n - a text string encoded using the specified encoding\n - any object implementing the buffer API.\n - an integer")
5+
import (
6+
"strings"
7+
)
8+
9+
varBytesType=ObjectType.NewType("bytes",
10+
`bytes(iterable_of_ints) -> bytes
11+
bytes(string, encoding[, errors]) -> bytes
12+
bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer
13+
bytes(int) -> bytes object of size given by the parameter initialized with null bytes
14+
bytes() -> empty bytes object
15+
16+
Construct an immutable array of bytes from:
17+
- an iterable yielding integers in range(256)
18+
- a text string encoded using the specified encoding
19+
- any object implementing the buffer API.
20+
- an integer`, BytesNew, nil)
621

722
typeBytes []byte
823

924
// Type of this Bytes object
1025
func (oBytes) Type() *Type{
1126
returnBytesType
1227
}
28+
29+
// BytesNew
30+
funcBytesNew(metatype*Type, argsTuple, kwargsStringDict) (resObject){
31+
varxObject
32+
varencodingObject
33+
varerrorsObject
34+
varNewObject
35+
kwlist:= []string{"source", "encoding", "errors"}
36+
37+
ParseTupleAndKeywords(args, kwargs, "|Oss:bytes", kwlist, &x, &encoding, &errors)
38+
ifx==nil{
39+
ifencoding!=nil||errors!=nil{
40+
panic(ExceptionNewf(TypeError, "encoding or errors without sequence argument"))
41+
}
42+
returnBytes{}
43+
}
44+
45+
ifs, ok:=x.(String); ok{
46+
// Encode via the codec registry
47+
ifencoding==nil{
48+
panic(ExceptionNewf(TypeError, "string argument without an encoding"))
49+
}
50+
encodingStr:=strings.ToLower(string(encoding.(String)))
51+
ifencodingStr=="utf-8"||encodingStr=="utf8"{
52+
returnBytes([]byte(s))
53+
}
54+
// FIXME
55+
// New = PyUnicode_AsEncodedString(x, encoding, errors)
56+
// assert(PyBytes_Check(New))
57+
// return New
58+
panic(ExceptionNewf(NotImplementedError, "String decode for %q not implemented", encodingStr))
59+
}
60+
61+
// We'd like to call PyObject_Bytes here, but we need to check for an
62+
// integer argument before deferring to PyBytes_FromObject, something
63+
// PyObject_Bytes doesn't do.
64+
varokbool
65+
ifI, ok:=x.(I__bytes__); ok{
66+
New=I.M__bytes__()
67+
} elseifNew, ok=TypeCall0(x, "__bytes__"); ok{
68+
} else{
69+
goto no_bytes_method
70+
}
71+
if_, ok=New.(Bytes); !ok{
72+
panic(ExceptionNewf(TypeError, "__bytes__ returned non-bytes (type %s)", New.Type().Name))
73+
}
74+
no_bytes_method:
75+
76+
// Is it an integer?
77+
if_, ok:=x.(Int); ok{
78+
size:=IndexInt(x)
79+
ifsize<0{
80+
panic(ExceptionNewf(ValueError, "negative count"))
81+
}
82+
returnmake(Bytes, size)
83+
}
84+
85+
// If it's not unicode, there can't be encoding or errors
86+
ifencoding!=nil||errors!=nil{
87+
panic(ExceptionNewf(TypeError, "encoding or errors without a string argument"))
88+
}
89+
90+
returnBytesFromObject(x)
91+
}
92+
93+
// Converts an object into bytes
94+
funcBytesFromObject(xObject) Bytes{
95+
// Look for special cases
96+
// FIXME implement converting from any object implementing the buffer API.
97+
switchz:=x.(type){
98+
caseBytes:
99+
// Immutable type so just return what was passed in
100+
returnz
101+
caseString:
102+
panic(ExceptionNewf(TypeError, "cannot convert unicode object to bytes"))
103+
}
104+
// Otherwise iterate through the whatever converting it into ints
105+
b:=Bytes{}
106+
Iterate(x, func(itemObject){
107+
value:=IndexInt(item)
108+
ifvalue<0||value>=256{
109+
panic(ExceptionNewf(ValueError, "bytes must be in range(0, 256)"))
110+
}
111+
b=append(b, byte(value))
112+
})
113+
returnb
114+
}

0 commit comments

Comments
(0)