dmg-builder 26.0.17 → 26.0.18

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.
@@ -1,48 +1,36 @@
1
- # -*- coding: utf-8 -*-
2
- from __future__ import unicode_literals
3
- from __future__ import print_function
4
- from __future__ import division
5
-
6
- import binascii
1
+ import plistlib
7
2
  import struct
8
- import biplist
9
- import mac_alias
10
3
 
11
- try:
12
- next
13
- except NameError:
14
- next = lambda x: x.next()
15
- try:
16
- unicode
17
- except NameError:
18
- unicode = str
4
+ import mac_alias
19
5
 
20
6
  from . import buddy
21
7
 
22
- class ILocCodec(object):
8
+
9
+ class ILocCodec:
23
10
  @staticmethod
24
11
  def encode(point):
25
- return struct.pack(b'>IIII', point[0], point[1],
26
- 0xffffffff, 0xffff0000)
12
+ return struct.pack(b">IIII", point[0], point[1], 0xFFFFFFFF, 0xFFFF0000)
27
13
 
28
14
  @staticmethod
29
15
  def decode(bytesData):
30
16
  if isinstance(bytesData, bytearray):
31
- x, y = struct.unpack_from(b'>II', bytes(bytesData[:8]))
17
+ x, y = struct.unpack_from(b">II", bytes(bytesData[:8]))
32
18
  else:
33
- x, y = struct.unpack(b'>II', bytesData[:8])
19
+ x, y = struct.unpack(b">II", bytesData[:8])
34
20
  return (x, y)
35
21
 
36
- class PlistCodec(object):
22
+
23
+ class PlistCodec:
37
24
  @staticmethod
38
25
  def encode(plist):
39
- return biplist.writePlistToString(plist)
26
+ return plistlib.dumps(plist, fmt=plistlib.FMT_BINARY)
40
27
 
41
28
  @staticmethod
42
29
  def decode(bytes):
43
- return biplist.readPlistFromString(bytes)
30
+ return plistlib.loads(bytes)
44
31
 
45
- class BookmarkCodec(object):
32
+
33
+ class BookmarkCodec:
46
34
  @staticmethod
47
35
  def encode(bmk):
48
36
  return bmk.to_bytes()
@@ -51,70 +39,73 @@ class BookmarkCodec(object):
51
39
  def decode(bytes):
52
40
  return mac_alias.Bookmark.from_bytes(bytes)
53
41
 
42
+
54
43
  # This list tells the code how to decode particular kinds of entry in the
55
44
  # .DS_Store file. This is really a convenience, and we currently only
56
45
  # support a tiny subset of the possible entry types.
57
46
  codecs = {
58
- b'Iloc': ILocCodec,
59
- b'bwsp': PlistCodec,
60
- b'lsvp': PlistCodec,
61
- b'lsvP': PlistCodec,
62
- b'icvp': PlistCodec,
63
- b'pBBk': BookmarkCodec
64
- }
65
-
66
- class DSStoreEntry(object):
47
+ b"Iloc": ILocCodec,
48
+ b"bwsp": PlistCodec,
49
+ b"lsvp": PlistCodec,
50
+ b"lsvP": PlistCodec,
51
+ b"icvp": PlistCodec,
52
+ b"pBBk": BookmarkCodec,
53
+ }
54
+
55
+
56
+ class DSStoreEntry:
67
57
  """Holds the data from an entry in a ``.DS_Store`` file. Note that this is
68
- not meant to represent the entry itself---i.e. if you change the type
69
- or value, your changes will *not* be reflected in the underlying file.
58
+ not meant to represent the entry itself---i.e. if you change the type or
59
+ value, your changes will *not* be reflected in the underlying file.
70
60
 
71
- If you want to make a change, you should either use the :class:`DSStore`
72
- object's :meth:`DSStore.insert` method (which will replace a key if it
73
- already exists), or the mapping access mode for :class:`DSStore` (often
74
- simpler anyway).
61
+ If you want to make a change, you should either use the
62
+ :class:`DSStore` object's :meth:`DSStore.insert` method (which will
63
+ replace a key if it already exists), or the mapping access mode for
64
+ :class:`DSStore` (often simpler anyway).
75
65
  """
66
+
76
67
  def __init__(self, filename, code, typecode, value=None):
77
68
  if str != bytes and type(filename) == bytes:
78
- filename = filename.decode('utf-8')
69
+ filename = filename.decode("utf-8")
79
70
 
80
71
  if not isinstance(code, bytes):
81
- code = code.encode('latin_1')
72
+ code = code.encode("latin_1")
82
73
 
83
74
  self.filename = filename
84
75
  self.code = code
85
76
  self.type = typecode
86
77
  self.value = value
87
-
78
+
88
79
  @classmethod
89
80
  def read(cls, block):
90
- """Read a ``.DS_Store`` entry from the containing Block"""
81
+ """Read a ``.DS_Store`` entry from the containing Block."""
91
82
  # First read the filename
92
- nlen = block.read(b'>I')[0]
93
- filename = block.read(2 * nlen).decode('utf-16be')
83
+ nlen = block.read(b">I")[0]
84
+ filename = block.read(2 * nlen).decode("utf-16be")
94
85
 
95
86
  # Next, read the code and type
96
- code, typecode = block.read(b'>4s4s')
87
+ code, typecode = block.read(b">4s4s")
97
88
 
98
89
  # Finally, read the data
99
- if typecode == b'bool':
100
- value = block.read(b'>?')[0]
101
- elif typecode == b'long' or typecode == b'shor':
102
- value = block.read(b'>I')[0]
103
- elif typecode == b'blob':
104
- vlen = block.read(b'>I')[0]
90
+ if typecode == b"bool":
91
+ value = block.read(b">?")[0]
92
+ elif typecode == b"long" or typecode == b"shor":
93
+ value = block.read(b">I")[0]
94
+ elif typecode == b"blob":
95
+ vlen = block.read(b">I")[0]
105
96
  value = block.read(vlen)
106
97
 
107
98
  codec = codecs.get(code, None)
108
99
  if codec:
109
100
  value = codec.decode(value)
110
101
  typecode = codec
111
- elif typecode == b'ustr':
112
- vlen = block.read(b'>I')[0]
113
- value = block.read(2 * vlen).decode('utf-16be')
114
- elif typecode == b'type':
115
- value = block.read(b'>4s')[0]
116
- elif typecode == b'comp' or typecode == b'dutc':
117
- value = block.read(b'>Q')[0]
102
+ elif typecode == b"ustr":
103
+ vlen = block.read(b">I")[0]
104
+ value = block.read(2 * vlen).decode("utf-16be")
105
+ elif typecode == b"type":
106
+ value = block.read(b">4s")[0]
107
+ elif typecode == b"comp" or typecode == b"dutc":
108
+ value = block.read(b">Q")[0]
118
109
  else:
119
110
  raise ValueError('Unknown type code "%s"' % typecode)
120
111
 
@@ -122,152 +113,138 @@ class DSStoreEntry(object):
122
113
 
123
114
  def __lt__(self, other):
124
115
  if not isinstance(other, DSStoreEntry):
125
- raise TypeError('Can only compare against other DSStoreEntry objects')
116
+ raise TypeError("Can only compare against other DSStoreEntry objects")
126
117
  sfl = self.filename.lower()
127
118
  ofl = other.filename.lower()
128
- return (sfl < ofl
129
- or (self.filename == other.filename
130
- and self.code < other.code))
119
+ return sfl < ofl or (self.filename == other.filename and self.code < other.code)
131
120
 
132
121
  def __le__(self, other):
133
122
  if not isinstance(other, DSStoreEntry):
134
- raise TypeError('Can only compare against other DSStoreEntry objects')
123
+ raise TypeError("Can only compare against other DSStoreEntry objects")
135
124
  sfl = self.filename.lower()
136
125
  ofl = other.filename.lower()
137
- return (sfl < ofl
138
- or (sfl == ofl
139
- and self.code <= other.code))
126
+ return sfl < ofl or (sfl == ofl and self.code <= other.code)
140
127
 
141
128
  def __eq__(self, other):
142
129
  if not isinstance(other, DSStoreEntry):
143
- raise TypeError('Can only compare against other DSStoreEntry objects')
130
+ raise TypeError("Can only compare against other DSStoreEntry objects")
144
131
  sfl = self.filename.lower()
145
132
  ofl = other.filename.lower()
146
- return (sfl == ofl
147
- and self.code == other.code)
133
+ return sfl == ofl and self.code == other.code
148
134
 
149
135
  def __ne__(self, other):
150
136
  if not isinstance(other, DSStoreEntry):
151
- raise TypeError('Can only compare against other DSStoreEntry objects')
137
+ raise TypeError("Can only compare against other DSStoreEntry objects")
152
138
  sfl = self.filename.lower()
153
139
  ofl = other.filename.lower()
154
- return (sfl != ofl
155
- or self.code != other.code)
140
+ return sfl != ofl or self.code != other.code
156
141
 
157
142
  def __gt__(self, other):
158
143
  if not isinstance(other, DSStoreEntry):
159
- raise TypeError('Can only compare against other DSStoreEntry objects')
144
+ raise TypeError("Can only compare against other DSStoreEntry objects")
160
145
  sfl = self.filename.lower()
161
146
  ofl = other.filename.lower()
162
-
147
+
163
148
  selfCode = self.code
164
149
  if str != bytes and type(selfCode) is bytes:
165
- selfCode = selfCode.decode('utf-8')
150
+ selfCode = selfCode.decode("utf-8")
166
151
  otherCode = other.code
167
152
  if str != bytes and type(otherCode) is bytes:
168
- otherCode = otherCode.decode('utf-8')
169
-
170
- return (sfl > ofl or (sfl == ofl and selfCode > otherCode))
153
+ otherCode = otherCode.decode("utf-8")
154
+
155
+ return sfl > ofl or (sfl == ofl and selfCode > otherCode)
171
156
 
172
157
  def __ge__(self, other):
173
158
  if not isinstance(other, DSStoreEntry):
174
- raise TypeError('Can only compare against other DSStoreEntry objects')
159
+ raise TypeError("Can only compare against other DSStoreEntry objects")
175
160
  sfl = self.filename.lower()
176
161
  ofl = other.filename.lower()
177
- return (sfl > ofl
178
- or (sfl == ofl
179
- and self.code >= other.code))
162
+ return sfl > ofl or (sfl == ofl and self.code >= other.code)
180
163
 
181
- def __cmp__(self, other):
182
- if not isinstance(other, DSStoreEntry):
183
- raise TypeError('Can only compare against other DSStoreEntry objects')
184
- r = cmp(self.filename.lower(), other.filename.lower())
185
- if r:
186
- return r
187
- return cmp(self.code, other.code)
188
-
189
164
  def byte_length(self):
190
- """Compute the length of this entry, in bytes"""
191
- utf16 = self.filename.encode('utf-16be')
192
- l = 4 + len(utf16) + 8
165
+ """Compute the length of this entry, in bytes."""
166
+ utf16 = self.filename.encode("utf-16be")
167
+ length = 4 + len(utf16) + 8
193
168
 
194
- if isinstance(self.type, unicode):
195
- entry_type = self.type.encode('latin_1')
169
+ if isinstance(self.type, str):
170
+ entry_type = self.type.encode("latin_1")
196
171
  value = self.value
197
172
  elif isinstance(self.type, (bytes, str)):
198
173
  entry_type = self.type
199
174
  value = self.value
200
175
  else:
201
- entry_type = b'blob'
176
+ entry_type = b"blob"
202
177
  value = self.type.encode(self.value)
203
-
204
- if entry_type == b'bool':
205
- l += 1
206
- elif entry_type == b'long' or entry_type == b'shor':
207
- l += 4
208
- elif entry_type == b'blob':
209
- l += 4 + len(value)
210
- elif entry_type == b'ustr':
211
- utf16 = value.encode('utf-16be')
212
- l += 4 + len(utf16)
213
- elif entry_type == b'type':
214
- l += 4
215
- elif entry_type == b'comp' or entry_type == b'dutc':
216
- l += 8
178
+
179
+ if entry_type == b"bool":
180
+ length += 1
181
+ elif entry_type == b"long" or entry_type == b"shor":
182
+ length += 4
183
+ elif entry_type == b"blob":
184
+ length += 4 + len(value)
185
+ elif entry_type == b"ustr":
186
+ utf16 = value.encode("utf-16be")
187
+ length += 4 + len(utf16)
188
+ elif entry_type == b"type":
189
+ length += 4
190
+ elif entry_type == b"comp" or entry_type == b"dutc":
191
+ length += 8
217
192
  else:
218
193
  raise ValueError('Unknown type code "%s"' % entry_type)
219
194
 
220
- return l
221
-
195
+ return length
196
+
222
197
  def write(self, block, insert=False):
223
- """Write this entry to the specified Block"""
198
+ """Write this entry to the specified Block."""
224
199
  if insert:
225
200
  w = block.insert
226
201
  else:
227
202
  w = block.write
228
203
 
229
- if isinstance(self.type, unicode):
230
- entry_type = self.type.encode('latin_1')
204
+ if isinstance(self.type, str):
205
+ entry_type = self.type.encode("latin_1")
231
206
  value = self.value
232
207
  elif isinstance(self.type, (bytes, str)):
233
208
  entry_type = self.type
234
209
  value = self.value
235
210
  else:
236
- entry_type = b'blob'
211
+ entry_type = b"blob"
237
212
  value = self.type.encode(self.value)
238
213
 
239
- utf16 = self.filename.encode('utf-16be')
240
- w(b'>I', len(utf16) // 2)
214
+ utf16 = self.filename.encode("utf-16be")
215
+ w(b">I", len(utf16) // 2)
241
216
  w(utf16)
242
- w(b'>4s4s', self.code, entry_type)
243
-
244
- if entry_type == b'bool':
245
- w(b'>?', value)
246
- elif entry_type == b'long' or entry_type == b'shor':
247
- w(b'>I', value)
248
- elif entry_type == b'blob':
249
- w(b'>I', len(value))
217
+ w(b">4s4s", self.code, entry_type)
218
+
219
+ if entry_type == b"bool":
220
+ w(b">?", value)
221
+ elif entry_type == b"long" or entry_type == b"shor":
222
+ w(b">I", value)
223
+ elif entry_type == b"blob":
224
+ w(b">I", len(value))
250
225
  w(value)
251
- elif entry_type == b'ustr':
252
- utf16 = value.encode('utf-16be')
253
- w(b'>I', len(utf16) // 2)
226
+ elif entry_type == b"ustr":
227
+ utf16 = value.encode("utf-16be")
228
+ w(b">I", len(utf16) // 2)
254
229
  w(utf16)
255
- elif entry_type == b'type':
256
- if isinstance(value, unicode):
257
- value = value.encode('latin_1')
258
- w(b'>4s', value)
259
- elif entry_type == b'comp' or entry_type == b'dutc':
260
- w(b'>Q', value)
230
+ elif entry_type == b"type":
231
+ if isinstance(value, str):
232
+ value = value.encode("latin_1")
233
+ w(b">4s", value)
234
+ elif entry_type == b"comp" or entry_type == b"dutc":
235
+ w(b">Q", value)
261
236
  else:
262
237
  raise ValueError('Unknown type code "%s"' % entry_type)
263
-
238
+
264
239
  def __repr__(self):
265
- return '<%s %s>' % (self.filename, self.code)
240
+ return f"<{self.filename} {self.code}>"
241
+
242
+
243
+ class DSStore:
244
+ """Python interface to a ``.DS_Store`` file. Works by manipulating the
245
+ file on the disk---so this code will work with ``.DS_Store`` files for.
266
246
 
267
- class DSStore(object):
268
- """Python interface to a ``.DS_Store`` file. Works by manipulating the file
269
- on the disk---so this code will work with ``.DS_Store`` files for *very*
270
- large directories.
247
+ *very* large directories.
271
248
 
272
249
  A :class:`DSStore` object can be used as if it was a mapping, e.g.::
273
250
 
@@ -280,7 +257,7 @@ class DSStore(object):
280
257
 
281
258
  Currently, we know how to decode "Iloc", "bwsp", "lsvp", "lsvP" and "icvp"
282
259
  blobs. "Iloc" decodes to an (x, y) tuple, while the others are all decoded
283
- using ``biplist``.
260
+ using ``biplist`` or ``plistlib`` depending on Python version.
284
261
 
285
262
  Assignment also works, e.g.::
286
263
 
@@ -292,38 +269,48 @@ class DSStore(object):
292
269
 
293
270
  This is usually going to be the most convenient interface, though
294
271
  occasionally (for instance when creating a new ``.DS_Store`` file) you
295
- may wish to drop down to using :class:`DSStoreEntry` objects directly."""
272
+ may wish to drop down to using :class:`DSStoreEntry` objects directly.
273
+ """
274
+
296
275
  def __init__(self, store):
297
276
  self._store = store
298
- self._superblk = self._store['DSDB']
277
+ self._superblk = self._store["DSDB"]
299
278
  with self._get_block(self._superblk) as s:
300
- self._rootnode, self._levels, self._records, \
301
- self._nodes, self._page_size = s.read(b'>IIIII')
279
+ (
280
+ self._rootnode,
281
+ self._levels,
282
+ self._records,
283
+ self._nodes,
284
+ self._page_size,
285
+ ) = s.read(b">IIIII")
302
286
  self._min_usage = 2 * self._page_size // 3
303
287
  self._dirty = False
304
-
288
+
305
289
  @classmethod
306
- def open(cls, file_or_name, mode='r+', initial_entries=None):
290
+ def open(cls, file_or_name, mode="r+", initial_entries=None):
307
291
  """Open a ``.DS_Store`` file; pass either a Python file object, or a
308
- filename in the ``file_or_name`` argument and a file access mode in
309
- the ``mode`` argument. If you are creating a new file using the "w"
310
- or "w+" modes, you may also specify a list of entries with which
311
- to initialise the file."""
292
+ filename in the ``file_or_name`` argument and a file access mode in the
293
+ ``mode`` argument.
294
+
295
+ If you are creating a new file using the "w" or "w+" modes, you
296
+ may also specify a list of entries with which to initialise the
297
+ file.
298
+ """
312
299
  store = buddy.Allocator.open(file_or_name, mode)
313
-
314
- if mode == 'w' or mode == 'w+':
300
+
301
+ if mode == "w" or mode == "w+":
315
302
  superblk = store.allocate(20)
316
- store['DSDB'] = superblk
303
+ store["DSDB"] = superblk
317
304
  page_size = 4096
318
-
305
+
319
306
  if not initial_entries:
320
307
  root = store.allocate(page_size)
321
-
308
+
322
309
  with store.get_block(root) as rootblk:
323
310
  rootblk.zero_fill()
324
311
 
325
312
  with store.get_block(superblk) as s:
326
- s.write(b'>IIIII', root, 0, 0, 1, page_size)
313
+ s.write(b">IIIII", root, 0, 0, 1, page_size)
327
314
  else:
328
315
  # Make sure they're in sorted order
329
316
  initial_entries = list(initial_entries)
@@ -357,48 +344,54 @@ class DSStore(object):
357
344
 
358
345
  if len(nodes) == 1:
359
346
  break
360
-
347
+
361
348
  current_level = next_level
362
349
  next_level = []
363
350
  ptr_size = 4
364
351
 
365
352
  # Allocate nodes
366
353
  ptrs = [store.allocate(page_size) for n in range(node_count)]
367
-
354
+
368
355
  # Generate nodes
369
356
  pointers = []
370
357
  prev_pointers = None
371
358
  for level in levels:
372
359
  ppndx = 0
373
- lptrs = ptrs[-len(level):]
374
- del ptrs[-len(level):]
360
+ lptrs = ptrs[-len(level) :]
361
+ del ptrs[-len(level) :]
375
362
  for node in level:
376
363
  ndx = lptrs.pop(0)
377
364
  if prev_pointers is None:
378
365
  with store.get_block(ndx) as block:
379
- block.write(b'>II', 0, len(node))
366
+ block.write(b">II", 0, len(node))
380
367
  for e in node:
381
368
  e.write(block)
382
369
  else:
383
370
  next_node = prev_pointers[ppndx + len(node)]
384
- node_ptrs = prev_pointers[ppndx:ppndx+len(node)]
385
-
371
+ node_ptrs = prev_pointers[ppndx : ppndx + len(node)]
372
+
386
373
  with store.get_block(ndx) as block:
387
- block.write(b'>II', next_node, len(node))
374
+ block.write(b">II", next_node, len(node))
388
375
  for ptr, e in zip(node_ptrs, node):
389
- block.write(b'>I', ptr)
376
+ block.write(b">I", ptr)
390
377
  e.write(block)
391
-
378
+
392
379
  pointers.append(ndx)
393
380
  prev_pointers = pointers
394
381
  pointers = []
395
-
382
+
396
383
  root = prev_pointers[0]
397
384
 
398
385
  with store.get_block(superblk) as s:
399
- s.write(b'>IIIII', root, len(levels), len(initial_entries),
400
- node_count, page_size)
401
-
386
+ s.write(
387
+ b">IIIII",
388
+ root,
389
+ len(levels),
390
+ len(initial_entries),
391
+ node_count,
392
+ page_size,
393
+ )
394
+
402
395
  return DSStore(store)
403
396
 
404
397
  def _get_block(self, number):
@@ -410,25 +403,31 @@ class DSStore(object):
410
403
  self._dirty = False
411
404
 
412
405
  with self._get_block(self._superblk) as s:
413
- s.write(b'>IIIII', self._rootnode, self._levels, self._records,
414
- self._nodes, self._page_size)
406
+ s.write(
407
+ b">IIIII",
408
+ self._rootnode,
409
+ self._levels,
410
+ self._records,
411
+ self._nodes,
412
+ self._page_size,
413
+ )
415
414
  self._store.flush()
416
415
 
417
416
  def close(self):
418
417
  """Flush dirty data and close the underlying file."""
419
418
  self.flush()
420
419
  self._store.close()
421
-
420
+
422
421
  def __enter__(self):
423
422
  return self
424
423
 
425
424
  def __exit__(self, exc_type, exc_value, traceback):
426
425
  self.close()
427
-
426
+
428
427
  # Internal B-Tree nodes look like this:
429
428
  #
430
429
  # [ next | count | (ptr0 | rec0) | (ptr1 | rec1) ... (ptrN | recN) ]
431
-
430
+
432
431
  # Leaf nodes look like this:
433
432
  #
434
433
  # [ 0 | count | rec0 | rec1 ... recN ]
@@ -438,10 +437,10 @@ class DSStore(object):
438
437
  if node is None:
439
438
  node = self._rootnode
440
439
  with self._get_block(node) as block:
441
- next_node, count = block.read(b'>II')
440
+ next_node, count = block.read(b">II")
442
441
  if next_node:
443
442
  for n in range(count):
444
- ptr = block.read(b'>I')[0]
443
+ ptr = block.read(b">I")[0]
445
444
  for e in self._traverse(ptr):
446
445
  yield e
447
446
  e = DSStoreEntry.read(block)
@@ -456,23 +455,30 @@ class DSStore(object):
456
455
  # Display the data in `node'
457
456
  def _dump_node(self, node):
458
457
  with self._get_block(node) as block:
459
- next_node, count = block.read(b'>II')
460
- print('next: %u\ncount: %u\n' % (next_node, count))
458
+ next_node, count = block.read(b">II")
459
+ print("next: %u\ncount: %u\n" % (next_node, count))
461
460
  for n in range(count):
462
461
  if next_node:
463
- ptr = block.read(b'>I')[0]
464
- print('%8u ' % ptr, end=' ')
462
+ ptr = block.read(b">I")[0]
463
+ print("%8u " % ptr, end=" ")
465
464
  else:
466
- print(' ', end=' ')
465
+ print(" ", end=" ")
467
466
  e = DSStoreEntry.read(block)
468
- print(e, ' (%u)' % e.byte_length())
469
- print('used: %u' % block.tell())
467
+ print(e, " (%u)" % e.byte_length())
468
+ print("used: %u" % block.tell())
470
469
 
471
470
  # Display the data in the super block
472
471
  def _dump_super(self):
473
- print('root: %u\nlevels: %u\nrecords: %u\nnodes: %u\npage-size: %u' \
474
- % (self._rootnode, self._levels, self._records,
475
- self._nodes, self._page_size))
472
+ print(
473
+ "root: %u\nlevels: %u\nrecords: %u\nnodes: %u\npage-size: %u"
474
+ % (
475
+ self._rootnode,
476
+ self._levels,
477
+ self._records,
478
+ self._nodes,
479
+ self._page_size,
480
+ )
481
+ )
476
482
 
477
483
  # Splits entries across two blocks, returning one pivot
478
484
  #
@@ -480,9 +486,9 @@ class DSStore(object):
480
486
  def _split2(self, blocks, entries, pointers, before, internal):
481
487
  left_block = blocks[0]
482
488
  right_block = blocks[1]
483
-
489
+
484
490
  count = len(entries)
485
-
491
+
486
492
  # Find the feasible splits
487
493
  best_split = None
488
494
  best_diff = None
@@ -492,7 +498,7 @@ class DSStore(object):
492
498
  # We can use a *single* node for this
493
499
  best_split = count
494
500
  else:
495
- # Split into two nodes
501
+ # Split into two nodes
496
502
  for n in range(1, count - 1):
497
503
  left_size = 8 + before[n]
498
504
  right_size = 8 + total - before[n + 1]
@@ -501,7 +507,7 @@ class DSStore(object):
501
507
  break
502
508
  if right_size > self._page_size:
503
509
  continue
504
-
510
+
505
511
  diff = abs(left_size - right_size)
506
512
 
507
513
  if best_split is None or diff < best_diff:
@@ -510,54 +516,53 @@ class DSStore(object):
510
516
 
511
517
  if best_split is None:
512
518
  return None
513
-
519
+
514
520
  # Write the nodes
515
521
  left_block.seek(0)
516
522
  if internal:
517
523
  next_node = pointers[best_split]
518
524
  else:
519
525
  next_node = 0
520
- left_block.write(b'>II', next_node, best_split)
526
+ left_block.write(b">II", next_node, best_split)
521
527
 
522
528
  for n in range(best_split):
523
529
  if internal:
524
- left_block.write(b'>I', pointers[n])
530
+ left_block.write(b">I", pointers[n])
525
531
  entries[n].write(left_block)
526
532
 
527
533
  left_block.zero_fill()
528
534
 
529
535
  if best_split == count:
530
536
  return []
531
-
537
+
532
538
  right_block.seek(0)
533
539
  if internal:
534
540
  next_node = pointers[count]
535
541
  else:
536
542
  next_node = 0
537
- right_block.write(b'>II', next_node, count - best_split - 1)
543
+ right_block.write(b">II", next_node, count - best_split - 1)
538
544
 
539
545
  for n in range(best_split + 1, count):
540
546
  if internal:
541
- right_block.write(b'>I', pointers[n])
547
+ right_block.write(b">I", pointers[n])
542
548
  entries[n].write(right_block)
543
549
 
544
550
  right_block.zero_fill()
545
-
551
+
546
552
  pivot = entries[best_split]
547
553
 
548
554
  return [pivot]
549
-
555
+
550
556
  def _split(self, node, entry, right_ptr=0):
551
557
  self._nodes += 1
552
558
  self._dirty = True
553
559
  new_right = self._store.allocate(self._page_size)
554
- with self._get_block(node) as block, \
555
- self._get_block(new_right) as right_block:
560
+ with self._get_block(node) as block, self._get_block(new_right) as right_block:
556
561
 
557
562
  # First, measure and extract all the elements
558
563
  entry_size = entry.byte_length()
559
- entry_pos = None
560
- next_node, count = block.read(b'>II')
564
+ # ?? entry_pos = None
565
+ next_node, count = block.read(b">II")
561
566
  if next_node:
562
567
  entry_size += 4
563
568
  pointers = []
@@ -567,11 +572,11 @@ class DSStore(object):
567
572
  for n in range(count):
568
573
  pos = block.tell()
569
574
  if next_node:
570
- ptr = block.read(b'>I')[0]
575
+ ptr = block.read(b">I")[0]
571
576
  pointers.append(ptr)
572
577
  e = DSStoreEntry.read(block)
573
578
  if e > entry:
574
- entry_pos = n
579
+ # ?? entry_pos = n
575
580
  entries.append(entry)
576
581
  pointers.append(right_ptr)
577
582
  before.append(total)
@@ -583,10 +588,10 @@ class DSStore(object):
583
588
  if next_node:
584
589
  pointers.append(next_node)
585
590
 
586
- pivot = self._split2([block, right_block],
587
- entries, pointers, before,
588
- bool(next_node))[0]
589
-
591
+ pivot = self._split2(
592
+ [block, right_block], entries, pointers, before, bool(next_node)
593
+ )[0]
594
+
590
595
  self._records += 1
591
596
  self._nodes += 1
592
597
  self._dirty = True
@@ -598,7 +603,7 @@ class DSStore(object):
598
603
  def _new_root(self, left, pivot, right):
599
604
  new_root = self._store.allocate(self._page_size)
600
605
  with self._get_block(new_root) as block:
601
- block.write(b'>III', right, 1, left)
606
+ block.write(b">III", right, 1, left)
602
607
  pivot.write(block)
603
608
  self._rootnode = new_root
604
609
  self._levels += 1
@@ -610,21 +615,21 @@ class DSStore(object):
610
615
  # pointer (inserted to the RIGHT of `entry')
611
616
  def _insert_inner(self, path, node, entry, right_ptr):
612
617
  with self._get_block(node) as block:
613
- next_node, count = block.read(b'>II')
618
+ next_node, count = block.read(b">II")
614
619
  insert_pos = None
615
620
  insert_ndx = None
616
621
  n = 0
617
622
  while n < count:
618
623
  pos = block.tell()
619
- ptr = block.read(b'>I')[0]
624
+ ptr = block.read(b">I")[0]
620
625
  e = DSStoreEntry.read(block)
621
626
  if e == entry:
622
627
  if n == count - 1:
623
628
  right_ptr = next_node
624
629
  next_node = ptr
625
- block_seek(pos)
630
+ block.seek(pos)
626
631
  else:
627
- right_ptr = block.read(b'>I')[0]
632
+ right_ptr = block.read(b">I")[0]
628
633
  block.seek(pos + 4)
629
634
  insert_pos = pos
630
635
  insert_ndx = n
@@ -651,32 +656,32 @@ class DSStore(object):
651
656
  else:
652
657
  if insert_ndx == count:
653
658
  block.seek(insert_pos)
654
- block.write(b'>I', next_node)
659
+ block.write(b">I", next_node)
655
660
  entry.write(block)
656
661
  next_node = right_ptr
657
662
  else:
658
663
  block.seek(insert_pos + 4)
659
664
  entry.write(block, True)
660
- block.insert('>I', right_ptr)
665
+ block.insert(">I", right_ptr)
661
666
  block.seek(0)
662
667
  count += 1
663
- block.write(b'>II', next_node, count)
668
+ block.write(b">II", next_node, count)
664
669
  self._records += 1
665
670
  self._dirty = True
666
671
 
667
672
  # Insert `entry' into the leaf node `node'
668
673
  def _insert_leaf(self, path, node, entry):
669
674
  with self._get_block(node) as block:
670
- next_node, count = block.read(b'>II')
675
+ next_node, count = block.read(b">II")
671
676
  insert_pos = None
672
- insert_ndx = None
677
+ # ?? insert_ndx = None
673
678
  n = 0
674
679
  while n < count:
675
680
  pos = block.tell()
676
681
  e = DSStoreEntry.read(block)
677
682
  if e == entry:
678
683
  insert_pos = pos
679
- insert_ndx = n
684
+ # ?? insert_ndx = n
680
685
  block.seek(pos)
681
686
  block.delete(e.byte_length())
682
687
  count -= 1
@@ -685,11 +690,11 @@ class DSStore(object):
685
690
  continue
686
691
  elif insert_pos is None and e > entry:
687
692
  insert_pos = pos
688
- insert_ndx = n
693
+ # ?? insert_ndx = n
689
694
  n += 1
690
695
  if insert_pos is None:
691
696
  insert_pos = block.tell()
692
- insert_ndx = count
697
+ # ?? insert_ndx = count
693
698
  remaining = self._page_size - block.tell()
694
699
 
695
700
  if remaining < entry.byte_length():
@@ -703,21 +708,21 @@ class DSStore(object):
703
708
  entry.write(block, True)
704
709
  block.seek(0)
705
710
  count += 1
706
- block.write(b'>II', next_node, count)
711
+ block.write(b">II", next_node, count)
707
712
  self._records += 1
708
713
  self._dirty = True
709
714
 
710
715
  def insert(self, entry):
711
- """Insert ``entry`` (which should be a :class:`DSStoreEntry`)
712
- into the B-Tree."""
716
+ """Insert ``entry`` (which should be a :class:`DSStoreEntry`) into the
717
+ B-Tree."""
713
718
  path = []
714
719
  node = self._rootnode
715
720
  while True:
716
721
  with self._get_block(node) as block:
717
- next_node, count = block.read(b'>II')
722
+ next_node, count = block.read(b">II")
718
723
  if next_node:
719
724
  for n in range(count):
720
- ptr = block.read(b'>I')[0]
725
+ ptr = block.read(b">I")[0]
721
726
  e = DSStoreEntry.read(block)
722
727
  if entry < e:
723
728
  next_node = ptr
@@ -735,12 +740,12 @@ class DSStore(object):
735
740
  # Return usage information for the specified `node'
736
741
  def _block_usage(self, node):
737
742
  with self._get_block(node) as block:
738
- next_node, count = block.read(b'>II')
743
+ next_node, count = block.read(b">II")
739
744
 
740
745
  for n in range(count):
741
746
  if next_node:
742
- ptr = block.read(b'>I')[0]
743
- e = DSStoreEntry.read(block)
747
+ block.read(b">I")[0]
748
+ DSStoreEntry.read(block)
744
749
 
745
750
  used = block.tell()
746
751
 
@@ -773,14 +778,14 @@ class DSStore(object):
773
778
  continue
774
779
 
775
780
  diff = abs(left_size - mid_size) * abs(right_size - mid_size)
776
-
781
+
777
782
  if best_split is None or diff < best_diff:
778
783
  best_split = (n, m, count)
779
784
  best_diff = diff
780
785
 
781
786
  if best_split is None:
782
787
  return None
783
-
788
+
784
789
  # Write the nodes
785
790
  prev_split = -1
786
791
  for block, split in zip(blocks, best_split):
@@ -789,15 +794,15 @@ class DSStore(object):
789
794
  next_node = pointers[split]
790
795
  else:
791
796
  next_node = 0
792
- block.write(b'>II', next_node, split)
797
+ block.write(b">II", next_node, split)
793
798
 
794
799
  for n in range(prev_split + 1, split):
795
800
  if internal:
796
- block.write(b'>I', pointers[n])
801
+ block.write(b">I", pointers[n])
797
802
  entries[n].write(block)
798
803
 
799
804
  block.zero_fill()
800
-
805
+
801
806
  prev_split = split
802
807
 
803
808
  return (entries[best_split[0]], entries[best_split[1]])
@@ -811,13 +816,13 @@ class DSStore(object):
811
816
  before = []
812
817
  total = 0
813
818
  ppivots = pivots + [None]
814
- for b,p in zip(blocks, ppivots):
819
+ for b, p in zip(blocks, ppivots):
815
820
  b.seek(0)
816
- next_node, count = b.read(b'>II')
821
+ next_node, count = b.read(b">II")
817
822
  for n in range(count):
818
823
  pos = b.tell()
819
824
  if next_node:
820
- ptr = b.read(b'>I')[0]
825
+ ptr = b.read(b">I")[0]
821
826
  pointers.append(ptr)
822
827
  e = DSStoreEntry.read(b)
823
828
  entries.append(e)
@@ -842,11 +847,11 @@ class DSStore(object):
842
847
  return
843
848
 
844
849
  with self._get_block(node) as block:
845
- next_node, count = block.read(b'>II')
846
-
850
+ next_node, count = block.read(b">II")
851
+
847
852
  with self._get_block(path[-1]) as parent:
848
853
  # Find the left and right siblings and respective pivots
849
- parent_next, parent_count = parent.read(b'>II')
854
+ parent_next, parent_count = parent.read(b">II")
850
855
  left_pos = None
851
856
  left_node = None
852
857
  left_pivot = None
@@ -857,7 +862,7 @@ class DSStore(object):
857
862
  prev_e = prev_ptr = prev_pos = None
858
863
  for n in range(parent_count):
859
864
  pos = parent.tell()
860
- ptr = parent.read(b'>I')[0]
865
+ ptr = parent.read(b">I")[0]
861
866
  e = DSStoreEntry.read(parent)
862
867
 
863
868
  if ptr == node:
@@ -870,7 +875,7 @@ class DSStore(object):
870
875
  right_node = ptr
871
876
  right_pos = pos
872
877
  break
873
-
878
+
874
879
  prev_e = e
875
880
  prev_ptr = ptr
876
881
  prev_pos = pos
@@ -884,24 +889,27 @@ class DSStore(object):
884
889
  right_node = parent_next
885
890
  right_pos = parent.tell()
886
891
 
887
- parent_used = parent.tell()
888
-
892
+ _ = parent.tell()
893
+
889
894
  if left_node and right_node:
890
- with self._get_block(left_node) as left, \
891
- self._get_block(right_node) as right:
895
+ with self._get_block(left_node) as left, self._get_block(
896
+ right_node
897
+ ) as right:
892
898
  blocks = [left, block, right]
893
899
  pivots = [left_pivot, right_pivot]
894
-
900
+
895
901
  entries, pointers, before = self._extract(blocks, pivots)
896
902
 
897
903
  # If there's a chance that we could use two pages instead
898
904
  # of three, go for it
899
- pivots = self._split2(blocks, entries, pointers,
900
- before, bool(next_node))
905
+ pivots = self._split2(
906
+ blocks, entries, pointers, before, bool(next_node)
907
+ )
901
908
  if pivots is None:
902
909
  ptrs = [left_node, node, right_node]
903
- pivots = self._split3(blocks, entries, pointers,
904
- before, bool(next_node))
910
+ pivots = self._split3(
911
+ blocks, entries, pointers, before, bool(next_node)
912
+ )
905
913
  else:
906
914
  if pivots:
907
915
  ptrs = [left_node, node]
@@ -913,7 +921,7 @@ class DSStore(object):
913
921
  self._store.release(right_node)
914
922
  self._nodes -= 1
915
923
  self._dirty = True
916
-
924
+
917
925
  # Remove the pivots from the parent
918
926
  with self._get_block(path[-1]) as parent:
919
927
  if right_node == parent_next:
@@ -925,11 +933,11 @@ class DSStore(object):
925
933
  parent.delete(right_pos - left_pos)
926
934
  parent.seek(0)
927
935
  parent_count -= 2
928
- parent.write(b'>II', parent_next, parent_count)
936
+ parent.write(b">II", parent_next, parent_count)
929
937
  self._records -= 2
930
-
938
+
931
939
  # Replace with those in pivots
932
- for e,rp in zip(pivots, ptrs[1:]):
940
+ for e, rp in zip(pivots, ptrs[1:]):
933
941
  self._insert_inner(path[:-1], path[-1], e, rp)
934
942
  elif left_node:
935
943
  with self._get_block(left_node) as left:
@@ -938,8 +946,9 @@ class DSStore(object):
938
946
 
939
947
  entries, pointers, before = self._extract(blocks, pivots)
940
948
 
941
- pivots = self._split2(blocks, entries, pointers,
942
- before, bool(next_node))
949
+ pivots = self._split2(
950
+ blocks, entries, pointers, before, bool(next_node)
951
+ )
943
952
 
944
953
  # Remove the pivot from the parent
945
954
  with self._get_block(path[-1]) as parent:
@@ -952,7 +961,7 @@ class DSStore(object):
952
961
  parent.delete(node_pos - left_pos)
953
962
  parent.seek(0)
954
963
  parent_count -= 1
955
- parent.write(b'>II', parent_next, parent_count)
964
+ parent.write(b">II", parent_next, parent_count)
956
965
  self._records -= 1
957
966
 
958
967
  # Replace the pivot
@@ -965,8 +974,9 @@ class DSStore(object):
965
974
 
966
975
  entries, pointers, before = self._extract(blocks, pivots)
967
976
 
968
- pivots = self._split2(blocks, entries, pointers,
969
- before, bool(next_node))
977
+ pivots = self._split2(
978
+ blocks, entries, pointers, before, bool(next_node)
979
+ )
970
980
 
971
981
  # Remove the pivot from the parent
972
982
  with self._get_block(path[-1]) as parent:
@@ -979,13 +989,12 @@ class DSStore(object):
979
989
  parent.delete(right_pos - node_pos)
980
990
  parent.seek(0)
981
991
  parent_count -= 1
982
- parent.write(b'>II', parent_next, parent_count)
992
+ parent.write(b">II", parent_next, parent_count)
983
993
  self._records -= 1
984
994
 
985
995
  # Replace the pivot
986
996
  if pivots:
987
- self._insert_inner(path[:-1], path[-1], pivots[0],
988
- right_node)
997
+ self._insert_inner(path[:-1], path[-1], pivots[0], right_node)
989
998
 
990
999
  if not path and not parent_count:
991
1000
  self._store.release(path[-1])
@@ -994,7 +1003,7 @@ class DSStore(object):
994
1003
  self._rootnode = node
995
1004
  else:
996
1005
  count, used = self._block_usage(path[-1])
997
-
1006
+
998
1007
  if used < self._page_size // 2:
999
1008
  self._rebalance(path[:-1], path[-1])
1000
1009
 
@@ -1002,31 +1011,32 @@ class DSStore(object):
1002
1011
  # lower-cased.
1003
1012
  def _delete_leaf(self, node, filename_lc, code):
1004
1013
  found = False
1005
-
1014
+
1006
1015
  with self._get_block(node) as block:
1007
- next_node, count = block.read(b'>II')
1016
+ next_node, count = block.read(b">II")
1008
1017
 
1009
1018
  for n in range(count):
1010
1019
  pos = block.tell()
1011
1020
  e = DSStoreEntry.read(block)
1012
- if e.filename.lower() == filename_lc \
1013
- and (code is None or e.code == code):
1021
+ if e.filename.lower() == filename_lc and (
1022
+ code is None or e.code == code
1023
+ ):
1014
1024
  block.seek(pos)
1015
1025
  block.delete(e.byte_length())
1016
1026
  found = True
1017
-
1027
+
1018
1028
  # This does not affect the loop; THIS IS NOT A BUG
1019
1029
  count -= 1
1020
1030
 
1021
1031
  self._records -= 1
1022
1032
  self._dirty = True
1023
-
1033
+
1024
1034
  if found:
1025
1035
  used = block.tell()
1026
-
1036
+
1027
1037
  block.seek(0)
1028
- block.write(b'>II', next_node, count)
1029
-
1038
+ block.write(b">II", next_node, count)
1039
+
1030
1040
  return used < self._page_size // 2
1031
1041
  else:
1032
1042
  return False
@@ -1040,7 +1050,7 @@ class DSStore(object):
1040
1050
  rebalance = None
1041
1051
  while True:
1042
1052
  with self._get_block(node) as block:
1043
- next_node, count = block.read(b'>II')
1053
+ next_node, count = block.read(b">II")
1044
1054
 
1045
1055
  if next_node:
1046
1056
  path.append(node)
@@ -1053,7 +1063,7 @@ class DSStore(object):
1053
1063
 
1054
1064
  count -= 1
1055
1065
  block.seek(0)
1056
- block.write(b'>II', next_node, count)
1066
+ block.write(b">II", next_node, count)
1057
1067
 
1058
1068
  if pos < self._page_size // 2:
1059
1069
  rebalance = (path, node)
@@ -1064,16 +1074,17 @@ class DSStore(object):
1064
1074
  # Delete an entry from an inner node, `node'
1065
1075
  def _delete_inner(self, path, node, filename_lc, code):
1066
1076
  rebalance = False
1067
-
1077
+
1068
1078
  with self._get_block(node) as block:
1069
- next_node, count = block.read(b'>II')
1079
+ next_node, count = block.read(b">II")
1070
1080
 
1071
1081
  for n in range(count):
1072
1082
  pos = block.tell()
1073
- ptr = block.read(b'>I')[0]
1083
+ ptr = block.read(b">I")[0]
1074
1084
  e = DSStoreEntry.read(block)
1075
- if e.filename.lower() == filename_lc \
1076
- and (code is None or e.code == code):
1085
+ if e.filename.lower() == filename_lc and (
1086
+ code is None or e.code == code
1087
+ ):
1077
1088
  # Take the largest from the left subtree
1078
1089
  rebalance, largest = self._take_largest(path, ptr)
1079
1090
 
@@ -1083,20 +1094,20 @@ class DSStore(object):
1083
1094
  next_node = ptr
1084
1095
  block.seek(pos)
1085
1096
  else:
1086
- right_ptr = block.read(b'>I')[0]
1097
+ right_ptr = block.read(b">I")[0]
1087
1098
  block.seek(pos + 4)
1088
-
1099
+
1089
1100
  block.delete(e.byte_length() + 4)
1090
1101
 
1091
1102
  count -= 1
1092
1103
  block.seek(0)
1093
- block.write(b'>II', next_node, count)
1104
+ block.write(b">II", next_node, count)
1094
1105
 
1095
1106
  self._records -= 1
1096
1107
  self._dirty = True
1097
-
1108
+
1098
1109
  break
1099
-
1110
+
1100
1111
  # Replace the pivot value
1101
1112
  self._insert_inner(path, node, largest, right_ptr)
1102
1113
 
@@ -1107,16 +1118,16 @@ class DSStore(object):
1107
1118
  return False
1108
1119
 
1109
1120
  def delete(self, filename, code):
1110
- """Delete an item, identified by ``filename`` and ``code``
1111
- from the B-Tree."""
1121
+ """Delete an item, identified by ``filename`` and ``code`` from the
1122
+ B-Tree."""
1112
1123
  if isinstance(filename, DSStoreEntry):
1113
1124
  code = filename.code
1114
1125
  filename = filename.filename
1115
1126
 
1116
1127
  # If we're deleting *every* node for "filename", we must recurse
1117
1128
  if code is None:
1118
- ###TODO: Fix this so we can do bulk deletes
1119
- raise ValueError('You must delete items individually. Sorry')
1129
+ # TODO: Fix this so we can do bulk deletes
1130
+ raise ValueError("You must delete items individually. Sorry")
1120
1131
 
1121
1132
  # Otherwise, we're deleting *one* specific node
1122
1133
  filename_lc = filename.lower()
@@ -1124,14 +1135,15 @@ class DSStore(object):
1124
1135
  node = self._rootnode
1125
1136
  while True:
1126
1137
  with self._get_block(node) as block:
1127
- next_node, count = block.read(b'>II')
1138
+ next_node, count = block.read(b">II")
1128
1139
  if next_node:
1129
1140
  for n in range(count):
1130
- ptr = block.read(b'>I')[0]
1141
+ ptr = block.read(b">I")[0]
1131
1142
  e = DSStoreEntry.read(block)
1132
1143
  e_lc = e.filename.lower()
1133
- if filename_lc < e_lc \
1134
- or (filename_lc == e_lc and code < e.code):
1144
+ if filename_lc < e_lc or (
1145
+ filename_lc == e_lc and code < e.code
1146
+ ):
1135
1147
  next_node = ptr
1136
1148
  break
1137
1149
  elif filename_lc == e_lc and code == e.code:
@@ -1147,12 +1159,12 @@ class DSStore(object):
1147
1159
  # Find implementation
1148
1160
  def _find(self, node, filename_lc, code=None):
1149
1161
  if code is not None and not isinstance(code, bytes):
1150
- code = code.encode('latin_1')
1162
+ code = code.encode("latin_1")
1151
1163
  with self._get_block(node) as block:
1152
- next_node, count = block.read(b'>II')
1164
+ next_node, count = block.read(b">II")
1153
1165
  if next_node:
1154
1166
  for n in range(count):
1155
- ptr = block.read(b'>I')[0]
1167
+ ptr = block.read(b">I")[0]
1156
1168
  e = DSStoreEntry.read(block)
1157
1169
  if filename_lc < e.filename.lower():
1158
1170
  for e in self._find(ptr, filename_lc, code):
@@ -1176,16 +1188,16 @@ class DSStore(object):
1176
1188
  yield e
1177
1189
  elif code < e.code:
1178
1190
  return
1179
-
1191
+
1180
1192
  def find(self, filename, code=None):
1181
- """Returns a generator that will iterate over matching entries in
1182
- the B-Tree."""
1193
+ """Returns a generator that will iterate over matching entries in the
1194
+ B-Tree."""
1183
1195
  if isinstance(filename, DSStoreEntry):
1184
1196
  code = filename.code
1185
1197
  filename = filename.filename
1186
1198
 
1187
1199
  filename_lc = filename.lower()
1188
-
1200
+
1189
1201
  return self._find(self._rootnode, filename_lc, code)
1190
1202
 
1191
1203
  def __len__(self):
@@ -1194,36 +1206,36 @@ class DSStore(object):
1194
1206
  def __iter__(self):
1195
1207
  return self._traverse(self._rootnode)
1196
1208
 
1197
- class Partial(object):
1209
+ class Partial:
1198
1210
  """This is used to implement indexing."""
1211
+
1199
1212
  def __init__(self, store, filename):
1200
1213
  self._store = store
1201
1214
  self._filename = filename
1202
1215
 
1203
1216
  def __getitem__(self, code):
1204
1217
  if code is None:
1205
- raise KeyError('no such key - [%s][None]' % self._filename)
1218
+ raise KeyError("no such key - [%s][None]" % self._filename)
1206
1219
 
1207
1220
  if not isinstance(code, bytes):
1208
- code = code.encode('latin_1')
1221
+ code = code.encode("latin_1")
1209
1222
 
1210
1223
  try:
1211
1224
  item = next(self._store.find(self._filename, code))
1212
1225
  except StopIteration:
1213
- raise KeyError('no such key - [%s][%s]' % (self._filename,
1214
- code))
1226
+ raise KeyError(f"no such key - [{self._filename}][{code}]")
1215
1227
 
1216
- if not isinstance(item.type, (bytes, str, unicode)):
1228
+ if not isinstance(item.type, (bytes, str)):
1217
1229
  return item.value
1218
-
1230
+
1219
1231
  return (item.type, item.value)
1220
-
1232
+
1221
1233
  def __setitem__(self, code, value):
1222
1234
  if code is None:
1223
- raise KeyError('bad key - [%s][None]' % self._filename)
1235
+ raise KeyError("bad key - [%s][None]" % self._filename)
1224
1236
 
1225
1237
  if not isinstance(code, bytes):
1226
- code = code.encode('latin_1')
1238
+ code = code.encode("latin_1")
1227
1239
 
1228
1240
  codec = codecs.get(code, None)
1229
1241
  if codec:
@@ -1232,20 +1244,19 @@ class DSStore(object):
1232
1244
  else:
1233
1245
  entry_type = value[0]
1234
1246
  entry_value = value[1]
1235
-
1236
- self._store.insert(DSStoreEntry(self._filename, code,
1237
- entry_type, entry_value))
1247
+
1248
+ self._store.insert(
1249
+ DSStoreEntry(self._filename, code, entry_type, entry_value)
1250
+ )
1238
1251
 
1239
1252
  def __delitem__(self, code):
1240
1253
  if code is None:
1241
- raise KeyError('no such key - [%s][None]' % self._filename)
1254
+ raise KeyError("no such key - [%s][None]" % self._filename)
1242
1255
 
1243
1256
  self._store.delete(self._filename, code)
1244
1257
 
1245
1258
  def __iter__(self):
1246
- for item in self._store.find(self._filename):
1247
- yield item
1259
+ yield from self._store.find(self._filename)
1248
1260
 
1249
1261
  def __getitem__(self, filename):
1250
1262
  return self.Partial(self, filename)
1251
-