dmg-builder 26.0.17 → 26.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/dmg.d.ts +33 -1
- package/out/dmg.js +7 -170
- package/out/dmg.js.map +1 -1
- package/out/dmgUtil.d.ts +16 -2
- package/out/dmgUtil.js +152 -1
- package/out/dmgUtil.js.map +1 -1
- package/out/hdiuil.js +7 -2
- package/out/hdiuil.js.map +1 -1
- package/package.json +3 -4
- package/vendor/biplist/__init__.py +75 -75
- package/vendor/dmgbuild/__init__.py +5 -0
- package/vendor/dmgbuild/__main__.py +67 -0
- package/vendor/dmgbuild/badge.py +104 -78
- package/vendor/dmgbuild/colors.py +239 -229
- package/vendor/dmgbuild/core.py +945 -274
- package/vendor/dmgbuild/licensing.py +329 -0
- package/vendor/dmgbuild/resources/builtin-arrow.tiff +0 -0
- package/vendor/ds_store/__init__.py +3 -1
- package/vendor/ds_store/__main__.py +102 -0
- package/vendor/ds_store/buddy.py +142 -134
- package/vendor/ds_store/store.py +333 -322
- package/vendor/mac_alias/__init__.py +43 -23
- package/vendor/mac_alias/alias.py +334 -224
- package/vendor/mac_alias/bookmark.py +283 -278
- package/vendor/mac_alias/osx.py +406 -302
- package/vendor/mac_alias/utils.py +10 -8
- package/vendor/run_dmgbuild.py +14 -0
package/vendor/ds_store/buddy.py
CHANGED
|
@@ -1,23 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
import os
|
|
1
|
+
import binascii
|
|
3
2
|
import bisect
|
|
3
|
+
import os
|
|
4
4
|
import struct
|
|
5
|
-
import binascii
|
|
6
5
|
|
|
7
|
-
try:
|
|
8
|
-
{}.iterkeys
|
|
9
|
-
iterkeys = lambda x: x.iterkeys()
|
|
10
|
-
except AttributeError:
|
|
11
|
-
iterkeys = lambda x: x.keys()
|
|
12
|
-
try:
|
|
13
|
-
unicode
|
|
14
|
-
except NameError:
|
|
15
|
-
unicode = str
|
|
16
6
|
|
|
17
7
|
class BuddyError(Exception):
|
|
18
8
|
pass
|
|
19
9
|
|
|
20
|
-
|
|
10
|
+
|
|
11
|
+
class Block:
|
|
21
12
|
def __init__(self, allocator, offset, size):
|
|
22
13
|
self._allocator = allocator
|
|
23
14
|
self._offset = offset
|
|
@@ -25,7 +16,7 @@ class Block(object):
|
|
|
25
16
|
self._value = bytearray(allocator.read(offset, size))
|
|
26
17
|
self._pos = 0
|
|
27
18
|
self._dirty = False
|
|
28
|
-
|
|
19
|
+
|
|
29
20
|
def __len__(self):
|
|
30
21
|
return self._size
|
|
31
22
|
|
|
@@ -34,7 +25,7 @@ class Block(object):
|
|
|
34
25
|
|
|
35
26
|
def __exit__(self, exc_type, exc_value, traceback):
|
|
36
27
|
self.close()
|
|
37
|
-
|
|
28
|
+
|
|
38
29
|
def close(self):
|
|
39
30
|
if self._dirty:
|
|
40
31
|
self.flush()
|
|
@@ -46,13 +37,13 @@ class Block(object):
|
|
|
46
37
|
|
|
47
38
|
def invalidate(self):
|
|
48
39
|
self._dirty = False
|
|
49
|
-
|
|
40
|
+
|
|
50
41
|
def zero_fill(self):
|
|
51
42
|
len = self._size - self._pos
|
|
52
|
-
zeroes = b
|
|
53
|
-
self._value[self._pos:self._size] = zeroes
|
|
43
|
+
zeroes = b"\0" * len
|
|
44
|
+
self._value[self._pos : self._size] = zeroes
|
|
54
45
|
self._dirty = True
|
|
55
|
-
|
|
46
|
+
|
|
56
47
|
def tell(self):
|
|
57
48
|
return self._pos
|
|
58
49
|
|
|
@@ -63,12 +54,12 @@ class Block(object):
|
|
|
63
54
|
pos = self._size - pos
|
|
64
55
|
|
|
65
56
|
if pos < 0 or pos > self._size:
|
|
66
|
-
raise ValueError(
|
|
57
|
+
raise ValueError("Seek out of range in Block instance")
|
|
67
58
|
|
|
68
59
|
self._pos = pos
|
|
69
60
|
|
|
70
61
|
def read(self, size_or_format):
|
|
71
|
-
if isinstance(size_or_format, (str,
|
|
62
|
+
if isinstance(size_or_format, (str, bytes)):
|
|
72
63
|
size = struct.calcsize(size_or_format)
|
|
73
64
|
fmt = size_or_format
|
|
74
65
|
else:
|
|
@@ -76,11 +67,11 @@ class Block(object):
|
|
|
76
67
|
fmt = None
|
|
77
68
|
|
|
78
69
|
if self._size - self._pos < size:
|
|
79
|
-
raise BuddyError(
|
|
70
|
+
raise BuddyError("Unable to read %lu bytes in block" % size)
|
|
80
71
|
|
|
81
|
-
data = self._value[self._pos:self._pos + size]
|
|
72
|
+
data = self._value[self._pos : self._pos + size]
|
|
82
73
|
self._pos += size
|
|
83
|
-
|
|
74
|
+
|
|
84
75
|
if fmt is not None:
|
|
85
76
|
if isinstance(data, bytearray):
|
|
86
77
|
return struct.unpack_from(fmt, bytes(data))
|
|
@@ -96,11 +87,11 @@ class Block(object):
|
|
|
96
87
|
data = data_or_format
|
|
97
88
|
|
|
98
89
|
if self._pos + len(data) > self._size:
|
|
99
|
-
raise ValueError(
|
|
90
|
+
raise ValueError("Attempt to write past end of Block")
|
|
100
91
|
|
|
101
|
-
self._value[self._pos:self._pos + len(data)] = data
|
|
92
|
+
self._value[self._pos : self._pos + len(data)] = data
|
|
102
93
|
self._pos += len(data)
|
|
103
|
-
|
|
94
|
+
|
|
104
95
|
self._dirty = True
|
|
105
96
|
|
|
106
97
|
def insert(self, data_or_format, *args):
|
|
@@ -109,78 +100,80 @@ class Block(object):
|
|
|
109
100
|
else:
|
|
110
101
|
data = data_or_format
|
|
111
102
|
|
|
112
|
-
del self._value[-len(data):]
|
|
113
|
-
self._value[self._pos:self._pos] = data
|
|
103
|
+
del self._value[-len(data) :]
|
|
104
|
+
self._value[self._pos : self._pos] = data
|
|
114
105
|
self._pos += len(data)
|
|
115
106
|
|
|
116
107
|
self._dirty = True
|
|
117
108
|
|
|
118
109
|
def delete(self, size):
|
|
119
110
|
if self._pos + size > self._size:
|
|
120
|
-
raise ValueError(
|
|
121
|
-
del self._value[self._pos:self._pos + size]
|
|
122
|
-
self._value += b
|
|
111
|
+
raise ValueError("Attempt to delete past end of Block")
|
|
112
|
+
del self._value[self._pos : self._pos + size]
|
|
113
|
+
self._value += b"\0" * size
|
|
123
114
|
self._dirty = True
|
|
124
|
-
|
|
115
|
+
|
|
125
116
|
def __str__(self):
|
|
126
117
|
return binascii.b2a_hex(self._value)
|
|
127
|
-
|
|
128
|
-
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class Allocator:
|
|
129
121
|
def __init__(self, the_file):
|
|
130
122
|
self._file = the_file
|
|
131
123
|
self._dirty = False
|
|
132
124
|
|
|
133
125
|
self._file.seek(0)
|
|
134
|
-
|
|
126
|
+
|
|
135
127
|
# Read the header
|
|
136
|
-
magic1, magic2, offset, size, offset2, self._unknown1
|
|
137
|
-
|
|
128
|
+
(magic1, magic2, offset, size, offset2, self._unknown1) = self.read(
|
|
129
|
+
-4, ">I4sIII16s"
|
|
130
|
+
)
|
|
138
131
|
|
|
139
|
-
if magic2 != b
|
|
140
|
-
raise BuddyError(
|
|
132
|
+
if magic2 != b"Bud1" or magic1 != 1:
|
|
133
|
+
raise BuddyError("Not a buddy file")
|
|
141
134
|
|
|
142
135
|
if offset != offset2:
|
|
143
|
-
raise BuddyError(
|
|
136
|
+
raise BuddyError("Root addresses differ")
|
|
144
137
|
|
|
145
138
|
self._root = Block(self, offset, size)
|
|
146
139
|
|
|
147
140
|
# Read the block offsets
|
|
148
|
-
count, self._unknown2 = self._root.read(
|
|
141
|
+
count, self._unknown2 = self._root.read(">II")
|
|
149
142
|
self._offsets = []
|
|
150
143
|
c = (count + 255) & ~255
|
|
151
144
|
while c:
|
|
152
|
-
self._offsets += self._root.read(
|
|
145
|
+
self._offsets += self._root.read(">256I")
|
|
153
146
|
c -= 256
|
|
154
147
|
self._offsets = self._offsets[:count]
|
|
155
|
-
|
|
148
|
+
|
|
156
149
|
# Read the TOC
|
|
157
150
|
self._toc = {}
|
|
158
|
-
count = self._root.read(
|
|
151
|
+
count = self._root.read(">I")[0]
|
|
159
152
|
for n in range(count):
|
|
160
|
-
nlen = self._root.read(
|
|
153
|
+
nlen = self._root.read("B")[0]
|
|
161
154
|
name = bytes(self._root.read(nlen))
|
|
162
|
-
value = self._root.read(
|
|
155
|
+
value = self._root.read(">I")[0]
|
|
163
156
|
self._toc[name] = value
|
|
164
157
|
|
|
165
158
|
# Read the free lists
|
|
166
159
|
self._free = []
|
|
167
160
|
for n in range(32):
|
|
168
|
-
count = self._root.read(
|
|
169
|
-
self._free.append(list(self._root.read(
|
|
170
|
-
|
|
161
|
+
count = self._root.read(">I")
|
|
162
|
+
self._free.append(list(self._root.read(">%uI" % count)))
|
|
163
|
+
|
|
171
164
|
@classmethod
|
|
172
|
-
def open(cls, file_or_name, mode=
|
|
173
|
-
if isinstance(file_or_name,
|
|
174
|
-
if not
|
|
175
|
-
mode = mode[:1] +
|
|
165
|
+
def open(cls, file_or_name, mode="r+"):
|
|
166
|
+
if isinstance(file_or_name, str):
|
|
167
|
+
if "b" not in mode:
|
|
168
|
+
mode = mode[:1] + "b" + mode[1:]
|
|
176
169
|
f = open(file_or_name, mode)
|
|
177
170
|
else:
|
|
178
171
|
f = file_or_name
|
|
179
172
|
|
|
180
|
-
if
|
|
173
|
+
if "w" in mode:
|
|
181
174
|
# Create an empty file in this case
|
|
182
175
|
f.truncate()
|
|
183
|
-
|
|
176
|
+
|
|
184
177
|
# An empty root block needs 1264 bytes:
|
|
185
178
|
#
|
|
186
179
|
# 0 4 offset count
|
|
@@ -190,7 +183,7 @@ class Allocator(object):
|
|
|
190
183
|
# 1032 4 toc count (0)
|
|
191
184
|
# 1036 228 free list
|
|
192
185
|
# total 1264
|
|
193
|
-
|
|
186
|
+
|
|
194
187
|
# The free list will contain the following:
|
|
195
188
|
#
|
|
196
189
|
# 0 5 * 4 no blocks of width less than 5
|
|
@@ -208,28 +201,38 @@ class Allocator(object):
|
|
|
208
201
|
# located at offset 2**n where n is its width.)
|
|
209
202
|
|
|
210
203
|
# Write the header
|
|
211
|
-
header = struct.pack(
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
204
|
+
header = struct.pack(
|
|
205
|
+
b">I4sIII16s",
|
|
206
|
+
1,
|
|
207
|
+
b"Bud1",
|
|
208
|
+
2048,
|
|
209
|
+
1264,
|
|
210
|
+
2048,
|
|
211
|
+
b"\x00\x00\x10\x0c"
|
|
212
|
+
b"\x00\x00\x00\x87"
|
|
213
|
+
b"\x00\x00\x20\x0b"
|
|
214
|
+
b"\x00\x00\x00\x00",
|
|
215
|
+
)
|
|
218
216
|
f.write(header)
|
|
219
|
-
f.write(b
|
|
220
|
-
|
|
217
|
+
f.write(b"\0" * 2016)
|
|
218
|
+
|
|
221
219
|
# Write the root block
|
|
222
|
-
free_list = [struct.pack(b
|
|
220
|
+
free_list = [struct.pack(b">5I", 0, 0, 0, 0, 0)]
|
|
223
221
|
for n in range(5, 11):
|
|
224
|
-
free_list.append(struct.pack(b
|
|
225
|
-
free_list.append(struct.pack(b
|
|
222
|
+
free_list.append(struct.pack(b">II", 1, 2**n))
|
|
223
|
+
free_list.append(struct.pack(b">I", 0))
|
|
226
224
|
for n in range(12, 31):
|
|
227
|
-
free_list.append(struct.pack(b
|
|
228
|
-
free_list.append(struct.pack(b
|
|
229
|
-
|
|
230
|
-
root = b
|
|
231
|
-
|
|
232
|
-
|
|
225
|
+
free_list.append(struct.pack(b">II", 1, 2**n))
|
|
226
|
+
free_list.append(struct.pack(b">I", 0))
|
|
227
|
+
|
|
228
|
+
root = b"".join(
|
|
229
|
+
[
|
|
230
|
+
struct.pack(b">III", 1, 0, 2048 | 5),
|
|
231
|
+
struct.pack(b">I", 0) * 255,
|
|
232
|
+
struct.pack(b">I", 0),
|
|
233
|
+
]
|
|
234
|
+
+ free_list
|
|
235
|
+
)
|
|
233
236
|
f.write(root)
|
|
234
237
|
|
|
235
238
|
return Allocator(f)
|
|
@@ -239,7 +242,7 @@ class Allocator(object):
|
|
|
239
242
|
|
|
240
243
|
def __exit__(self, exc_type, exc_value, traceback):
|
|
241
244
|
self.close()
|
|
242
|
-
|
|
245
|
+
|
|
243
246
|
def close(self):
|
|
244
247
|
self.flush()
|
|
245
248
|
self._file.close()
|
|
@@ -252,51 +255,57 @@ class Allocator(object):
|
|
|
252
255
|
self._write_root_block_into(rblk)
|
|
253
256
|
|
|
254
257
|
addr = self._offsets[0]
|
|
255
|
-
offset = addr & ~
|
|
256
|
-
size = 1 << (addr &
|
|
258
|
+
offset = addr & ~0x1F
|
|
259
|
+
size = 1 << (addr & 0x1F)
|
|
257
260
|
|
|
258
261
|
self._file.seek(0, os.SEEK_SET)
|
|
259
|
-
self._file.write(
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
262
|
+
self._file.write(
|
|
263
|
+
struct.pack(
|
|
264
|
+
b">I4sIII16s", 1, b"Bud1", offset, size, offset, self._unknown1
|
|
265
|
+
)
|
|
266
|
+
)
|
|
263
267
|
|
|
264
268
|
self._dirty = False
|
|
265
|
-
|
|
269
|
+
|
|
266
270
|
self._file.flush()
|
|
267
|
-
|
|
271
|
+
|
|
268
272
|
def read(self, offset, size_or_format):
|
|
269
|
-
"""Read data at `offset', or raise an exception.
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
+
"""Read data at `offset', or raise an exception.
|
|
274
|
+
|
|
275
|
+
`size_or_format' may either be a byte count, in which case we
|
|
276
|
+
return raw data, or a format string for `struct.unpack', in
|
|
277
|
+
which case we work out the size and unpack the data before
|
|
278
|
+
returning it.
|
|
279
|
+
"""
|
|
273
280
|
# N.B. There is a fixed offset of four bytes(!)
|
|
274
281
|
self._file.seek(offset + 4, os.SEEK_SET)
|
|
275
282
|
|
|
276
|
-
if isinstance(size_or_format,
|
|
283
|
+
if isinstance(size_or_format, str):
|
|
277
284
|
size = struct.calcsize(size_or_format)
|
|
278
285
|
fmt = size_or_format
|
|
279
286
|
else:
|
|
280
287
|
size = size_or_format
|
|
281
288
|
fmt = None
|
|
282
|
-
|
|
289
|
+
|
|
283
290
|
ret = self._file.read(size)
|
|
284
291
|
if len(ret) < size:
|
|
285
|
-
ret += b
|
|
292
|
+
ret += b"\0" * (size - len(ret))
|
|
286
293
|
|
|
287
294
|
if fmt is not None:
|
|
288
295
|
if isinstance(ret, bytearray):
|
|
289
296
|
ret = struct.unpack_from(fmt, bytes(ret))
|
|
290
297
|
else:
|
|
291
298
|
ret = struct.unpack(fmt, ret)
|
|
292
|
-
|
|
299
|
+
|
|
293
300
|
return ret
|
|
294
301
|
|
|
295
302
|
def write(self, offset, data_or_format, *args):
|
|
296
|
-
"""Write data at `offset', or raise an exception.
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
303
|
+
"""Write data at `offset', or raise an exception.
|
|
304
|
+
|
|
305
|
+
`data_or_format' may either be the data to write, or a format
|
|
306
|
+
string for `struct.pack', in which case we pack the additional
|
|
307
|
+
arguments and write the resulting data.
|
|
308
|
+
"""
|
|
300
309
|
# N.B. There is a fixed offset of four bytes(!)
|
|
301
310
|
self._file.seek(offset + 4, os.SEEK_SET)
|
|
302
311
|
|
|
@@ -313,11 +322,11 @@ class Allocator(object):
|
|
|
313
322
|
except IndexError:
|
|
314
323
|
return None
|
|
315
324
|
|
|
316
|
-
offset = addr & ~
|
|
317
|
-
size = 1 << (addr &
|
|
325
|
+
offset = addr & ~0x1F
|
|
326
|
+
size = 1 << (addr & 0x1F)
|
|
318
327
|
|
|
319
328
|
return Block(self, offset, size)
|
|
320
|
-
|
|
329
|
+
|
|
321
330
|
def _root_block_size(self):
|
|
322
331
|
"""Return the number of bytes required by the root block."""
|
|
323
332
|
# Offsets
|
|
@@ -330,62 +339,62 @@ class Allocator(object):
|
|
|
330
339
|
|
|
331
340
|
# Free list
|
|
332
341
|
size += sum([4 + 4 * len(fl) for fl in self._free])
|
|
333
|
-
|
|
342
|
+
|
|
334
343
|
return size
|
|
335
344
|
|
|
336
345
|
def _write_root_block_into(self, block):
|
|
337
346
|
# Offsets
|
|
338
|
-
block.write(
|
|
339
|
-
block.write(
|
|
347
|
+
block.write(">II", len(self._offsets), self._unknown2)
|
|
348
|
+
block.write(">%uI" % len(self._offsets), *self._offsets)
|
|
340
349
|
extra = len(self._offsets) & 255
|
|
341
350
|
if extra:
|
|
342
|
-
block.write(b
|
|
351
|
+
block.write(b"\0\0\0\0" * (256 - extra))
|
|
343
352
|
|
|
344
353
|
# TOC
|
|
345
354
|
keys = list(self._toc.keys())
|
|
346
355
|
keys.sort()
|
|
347
356
|
|
|
348
|
-
block.write(
|
|
357
|
+
block.write(">I", len(keys))
|
|
349
358
|
for k in keys:
|
|
350
|
-
block.write(
|
|
359
|
+
block.write("B", len(k))
|
|
351
360
|
block.write(k)
|
|
352
|
-
block.write(
|
|
361
|
+
block.write(">I", self._toc[k])
|
|
353
362
|
|
|
354
363
|
# Free list
|
|
355
364
|
for w, f in enumerate(self._free):
|
|
356
|
-
block.write(
|
|
365
|
+
block.write(">I", len(f))
|
|
357
366
|
if len(f):
|
|
358
|
-
block.write(
|
|
367
|
+
block.write(">%uI" % len(f), *f)
|
|
359
368
|
|
|
360
369
|
def _buddy(self, offset, width):
|
|
361
370
|
f = self._free[width]
|
|
362
371
|
b = offset ^ (1 << width)
|
|
363
|
-
|
|
372
|
+
|
|
364
373
|
try:
|
|
365
374
|
ndx = f.index(b)
|
|
366
375
|
except ValueError:
|
|
367
376
|
ndx = None
|
|
368
|
-
|
|
377
|
+
|
|
369
378
|
return (f, b, ndx)
|
|
370
379
|
|
|
371
380
|
def _release(self, offset, width):
|
|
372
381
|
# Coalesce
|
|
373
382
|
while True:
|
|
374
|
-
f,b,ndx = self._buddy(offset, width)
|
|
383
|
+
f, b, ndx = self._buddy(offset, width)
|
|
375
384
|
|
|
376
385
|
if ndx is None:
|
|
377
386
|
break
|
|
378
|
-
|
|
387
|
+
|
|
379
388
|
offset &= b
|
|
380
389
|
width += 1
|
|
381
390
|
del f[ndx]
|
|
382
|
-
|
|
391
|
+
|
|
383
392
|
# Add to the list
|
|
384
393
|
bisect.insort(f, offset)
|
|
385
394
|
|
|
386
395
|
# Mark as dirty
|
|
387
396
|
self._dirty = True
|
|
388
|
-
|
|
397
|
+
|
|
389
398
|
def _alloc(self, width):
|
|
390
399
|
w = width
|
|
391
400
|
while not self._free[w]:
|
|
@@ -407,15 +416,15 @@ class Allocator(object):
|
|
|
407
416
|
except ValueError:
|
|
408
417
|
block = len(self._offsets)
|
|
409
418
|
self._offsets.append(0)
|
|
410
|
-
|
|
419
|
+
|
|
411
420
|
# Compute block width
|
|
412
421
|
width = max(bytes.bit_length(), 5)
|
|
413
422
|
|
|
414
423
|
addr = self._offsets[block]
|
|
415
|
-
offset = addr & ~
|
|
416
|
-
|
|
424
|
+
offset = addr & ~0x1F
|
|
425
|
+
|
|
417
426
|
if addr:
|
|
418
|
-
blkwidth = addr &
|
|
427
|
+
blkwidth = addr & 0x1F
|
|
419
428
|
if blkwidth == width:
|
|
420
429
|
return block
|
|
421
430
|
self._release(offset, width)
|
|
@@ -424,13 +433,13 @@ class Allocator(object):
|
|
|
424
433
|
offset = self._alloc(width)
|
|
425
434
|
self._offsets[block] = offset | width
|
|
426
435
|
return block
|
|
427
|
-
|
|
436
|
+
|
|
428
437
|
def release(self, block):
|
|
429
438
|
addr = self._offsets[block]
|
|
430
439
|
|
|
431
440
|
if addr:
|
|
432
|
-
width = addr &
|
|
433
|
-
offset = addr & ~
|
|
441
|
+
width = addr & 0x1F
|
|
442
|
+
offset = addr & ~0x1F
|
|
434
443
|
self._release(offset, width)
|
|
435
444
|
|
|
436
445
|
if block == len(self._offsets):
|
|
@@ -442,37 +451,36 @@ class Allocator(object):
|
|
|
442
451
|
return len(self._toc)
|
|
443
452
|
|
|
444
453
|
def __getitem__(self, key):
|
|
445
|
-
if not isinstance(key,
|
|
446
|
-
raise TypeError(
|
|
454
|
+
if not isinstance(key, str):
|
|
455
|
+
raise TypeError("Keys must be of string type")
|
|
447
456
|
if not isinstance(key, bytes):
|
|
448
|
-
key = key.encode(
|
|
457
|
+
key = key.encode("latin_1")
|
|
449
458
|
return self._toc[key]
|
|
450
459
|
|
|
451
460
|
def __setitem__(self, key, value):
|
|
452
|
-
if not isinstance(key,
|
|
453
|
-
raise TypeError(
|
|
461
|
+
if not isinstance(key, str):
|
|
462
|
+
raise TypeError("Keys must be of string type")
|
|
454
463
|
if not isinstance(key, bytes):
|
|
455
|
-
key = key.encode(
|
|
464
|
+
key = key.encode("latin_1")
|
|
456
465
|
self._toc[key] = value
|
|
457
466
|
self._dirty = True
|
|
458
467
|
|
|
459
468
|
def __delitem__(self, key):
|
|
460
|
-
if not isinstance(key,
|
|
461
|
-
raise TypeError(
|
|
469
|
+
if not isinstance(key, str):
|
|
470
|
+
raise TypeError("Keys must be of string type")
|
|
462
471
|
if not isinstance(key, bytes):
|
|
463
|
-
key = key.encode(
|
|
472
|
+
key = key.encode("latin_1")
|
|
464
473
|
del self._toc[key]
|
|
465
474
|
self._dirty = True
|
|
466
475
|
|
|
467
476
|
def iterkeys(self):
|
|
468
|
-
return
|
|
477
|
+
return self._toc.keys()
|
|
469
478
|
|
|
470
479
|
def keys(self):
|
|
471
|
-
return
|
|
480
|
+
return self._toc.keys()
|
|
472
481
|
|
|
473
482
|
def __iter__(self):
|
|
474
|
-
return
|
|
483
|
+
return self._toc.keys()
|
|
475
484
|
|
|
476
485
|
def __contains__(self, key):
|
|
477
486
|
return key in self._toc
|
|
478
|
-
|