@@ -345,31 +345,27 @@ def _set_text(self, text: bytes) -> None:
|
345 | 345 | def _unpack_text_into_properties(self) -> None: |
346 | 346 | """Unpacks the text field into properties""" |
347 | 347 | text = self.text |
348 | | -end = len(text) |
349 | | -if end == 0: |
| 348 | +if not text: |
350 | 349 | # Properties should be set atomically |
351 | 350 | # in case another thread is reading them |
352 | 351 | self._properties = {} |
353 | 352 | return |
354 | 353 | |
355 | | -result: Dict[Union[str, bytes], Optional[Union[str, bytes]]] = {} |
356 | 354 | index = 0 |
357 | | -strs: List[bytes] = [] |
| 355 | +pairs: List[bytes] = [] |
| 356 | +end = len(text) |
358 | 357 | while index < end: |
359 | 358 | length = text[index] |
360 | 359 | index += 1 |
361 | | -strs.append(text[index : index + length]) |
| 360 | +pairs.append(text[index : index + length]) |
362 | 361 | index += length |
363 | 362 | |
364 | | -for s in strs: |
365 | | -key, _, value = s.partition(b'=') |
366 | | -# Only update non-existent properties |
367 | | -if key and key not in result: |
368 | | -result[key] = value or None |
369 | | - |
370 | | -# Properties should be set atomically |
371 | | -# in case another thread is reading them |
372 | | -self._properties = result |
| 363 | +# Reverse the list so that the first item in the list |
| 364 | +# is the last item in the text field. This is important |
| 365 | +# to preserve backwards compatibility where the first |
| 366 | +# key always wins if the key is seen multiple times. |
| 367 | +pairs.reverse() |
| 368 | +self._properties = {key: value or None for key, _, value in (pair.partition(b'=') for pair in pairs)} |
373 | 369 | |
374 | 370 | def get_name(self) -> str: |
375 | 371 | """Name accessor""" |
|