| OLD | NEW |
| 1 # Protocol Buffers - Google's data interchange format | 1 # Protocol Buffers - Google's data interchange format |
| 2 # Copyright 2008 Google Inc. All rights reserved. | 2 # Copyright 2008 Google Inc. All rights reserved. |
| 3 # https://developers.google.com/protocol-buffers/ | 3 # https://developers.google.com/protocol-buffers/ |
| 4 # | 4 # |
| 5 # Redistribution and use in source and binary forms, with or without | 5 # Redistribution and use in source and binary forms, with or without |
| 6 # modification, are permitted provided that the following conditions are | 6 # modification, are permitted provided that the following conditions are |
| 7 # met: | 7 # met: |
| 8 # | 8 # |
| 9 # * Redistributions of source code must retain the above copyright | 9 # * Redistributions of source code must retain the above copyright |
| 10 # notice, this list of conditions and the following disclaimer. | 10 # notice, this list of conditions and the following disclaimer. |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 raise TypeError('Can only compare repeated composite fields against ' | 429 raise TypeError('Can only compare repeated composite fields against ' |
| 430 'other repeated composite fields.') | 430 'other repeated composite fields.') |
| 431 return self._values == other._values | 431 return self._values == other._values |
| 432 | 432 |
| 433 | 433 |
| 434 class ScalarMap(MutableMapping): | 434 class ScalarMap(MutableMapping): |
| 435 | 435 |
| 436 """Simple, type-checked, dict-like container for holding repeated scalars.""" | 436 """Simple, type-checked, dict-like container for holding repeated scalars.""" |
| 437 | 437 |
| 438 # Disallows assignment to other attributes. | 438 # Disallows assignment to other attributes. |
| 439 __slots__ = ['_key_checker', '_value_checker', '_values', '_message_listener'] | 439 __slots__ = ['_key_checker', '_value_checker', '_values', '_message_listener', |
| 440 '_entry_descriptor'] |
| 440 | 441 |
| 441 def __init__(self, message_listener, key_checker, value_checker): | 442 def __init__(self, message_listener, key_checker, value_checker, |
| 443 entry_descriptor): |
| 442 """ | 444 """ |
| 443 Args: | 445 Args: |
| 444 message_listener: A MessageListener implementation. | 446 message_listener: A MessageListener implementation. |
| 445 The ScalarMap will call this object's Modified() method when it | 447 The ScalarMap will call this object's Modified() method when it |
| 446 is modified. | 448 is modified. |
| 447 key_checker: A type_checkers.ValueChecker instance to run on keys | 449 key_checker: A type_checkers.ValueChecker instance to run on keys |
| 448 inserted into this container. | 450 inserted into this container. |
| 449 value_checker: A type_checkers.ValueChecker instance to run on values | 451 value_checker: A type_checkers.ValueChecker instance to run on values |
| 450 inserted into this container. | 452 inserted into this container. |
| 453 entry_descriptor: The MessageDescriptor of a map entry: key and value. |
| 451 """ | 454 """ |
| 452 self._message_listener = message_listener | 455 self._message_listener = message_listener |
| 453 self._key_checker = key_checker | 456 self._key_checker = key_checker |
| 454 self._value_checker = value_checker | 457 self._value_checker = value_checker |
| 458 self._entry_descriptor = entry_descriptor |
| 455 self._values = {} | 459 self._values = {} |
| 456 | 460 |
| 457 def __getitem__(self, key): | 461 def __getitem__(self, key): |
| 458 try: | 462 try: |
| 459 return self._values[key] | 463 return self._values[key] |
| 460 except KeyError: | 464 except KeyError: |
| 461 key = self._key_checker.CheckValue(key) | 465 key = self._key_checker.CheckValue(key) |
| 462 val = self._value_checker.DefaultValue() | 466 val = self._value_checker.DefaultValue() |
| 463 self._values[key] = val | 467 self._values[key] = val |
| 464 return val | 468 return val |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 # self._values is to ensure that its size changes. | 510 # self._values is to ensure that its size changes. |
| 507 original = self._values | 511 original = self._values |
| 508 self._values = original.copy() | 512 self._values = original.copy() |
| 509 original[None] = None | 513 original[None] = None |
| 510 | 514 |
| 511 # This is defined in the abstract base, but we can do it much more cheaply. | 515 # This is defined in the abstract base, but we can do it much more cheaply. |
| 512 def clear(self): | 516 def clear(self): |
| 513 self._values.clear() | 517 self._values.clear() |
| 514 self._message_listener.Modified() | 518 self._message_listener.Modified() |
| 515 | 519 |
| 520 def GetEntryClass(self): |
| 521 return self._entry_descriptor._concrete_class |
| 522 |
| 516 | 523 |
| 517 class MessageMap(MutableMapping): | 524 class MessageMap(MutableMapping): |
| 518 | 525 |
| 519 """Simple, type-checked, dict-like container for with submessage values.""" | 526 """Simple, type-checked, dict-like container for with submessage values.""" |
| 520 | 527 |
| 521 # Disallows assignment to other attributes. | 528 # Disallows assignment to other attributes. |
| 522 __slots__ = ['_key_checker', '_values', '_message_listener', | 529 __slots__ = ['_key_checker', '_values', '_message_listener', |
| 523 '_message_descriptor'] | 530 '_message_descriptor', '_entry_descriptor'] |
| 524 | 531 |
| 525 def __init__(self, message_listener, message_descriptor, key_checker): | 532 def __init__(self, message_listener, message_descriptor, key_checker, |
| 533 entry_descriptor): |
| 526 """ | 534 """ |
| 527 Args: | 535 Args: |
| 528 message_listener: A MessageListener implementation. | 536 message_listener: A MessageListener implementation. |
| 529 The ScalarMap will call this object's Modified() method when it | 537 The ScalarMap will call this object's Modified() method when it |
| 530 is modified. | 538 is modified. |
| 531 key_checker: A type_checkers.ValueChecker instance to run on keys | 539 key_checker: A type_checkers.ValueChecker instance to run on keys |
| 532 inserted into this container. | 540 inserted into this container. |
| 533 value_checker: A type_checkers.ValueChecker instance to run on values | 541 value_checker: A type_checkers.ValueChecker instance to run on values |
| 534 inserted into this container. | 542 inserted into this container. |
| 543 entry_descriptor: The MessageDescriptor of a map entry: key and value. |
| 535 """ | 544 """ |
| 536 self._message_listener = message_listener | 545 self._message_listener = message_listener |
| 537 self._message_descriptor = message_descriptor | 546 self._message_descriptor = message_descriptor |
| 538 self._key_checker = key_checker | 547 self._key_checker = key_checker |
| 548 self._entry_descriptor = entry_descriptor |
| 539 self._values = {} | 549 self._values = {} |
| 540 | 550 |
| 541 def __getitem__(self, key): | 551 def __getitem__(self, key): |
| 542 try: | 552 try: |
| 543 return self._values[key] | 553 return self._values[key] |
| 544 except KeyError: | 554 except KeyError: |
| 545 key = self._key_checker.CheckValue(key) | 555 key = self._key_checker.CheckValue(key) |
| 546 new_element = self._message_descriptor._concrete_class() | 556 new_element = self._message_descriptor._concrete_class() |
| 547 new_element._SetListener(self._message_listener) | 557 new_element._SetListener(self._message_listener) |
| 548 self._values[key] = new_element | 558 self._values[key] = new_element |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 return len(self._values) | 597 return len(self._values) |
| 588 | 598 |
| 589 def __iter__(self): | 599 def __iter__(self): |
| 590 return iter(self._values) | 600 return iter(self._values) |
| 591 | 601 |
| 592 def __repr__(self): | 602 def __repr__(self): |
| 593 return repr(self._values) | 603 return repr(self._values) |
| 594 | 604 |
| 595 def MergeFrom(self, other): | 605 def MergeFrom(self, other): |
| 596 for key in other: | 606 for key in other: |
| 597 self[key].MergeFrom(other[key]) | 607 # According to documentation: "When parsing from the wire or when merging, |
| 608 # if there are duplicate map keys the last key seen is used". |
| 609 if key in self: |
| 610 del self[key] |
| 611 self[key].CopyFrom(other[key]) |
| 598 # self._message_listener.Modified() not required here, because | 612 # self._message_listener.Modified() not required here, because |
| 599 # mutations to submessages already propagate. | 613 # mutations to submessages already propagate. |
| 600 | 614 |
| 601 def InvalidateIterators(self): | 615 def InvalidateIterators(self): |
| 602 # It appears that the only way to reliably invalidate iterators to | 616 # It appears that the only way to reliably invalidate iterators to |
| 603 # self._values is to ensure that its size changes. | 617 # self._values is to ensure that its size changes. |
| 604 original = self._values | 618 original = self._values |
| 605 self._values = original.copy() | 619 self._values = original.copy() |
| 606 original[None] = None | 620 original[None] = None |
| 607 | 621 |
| 608 # This is defined in the abstract base, but we can do it much more cheaply. | 622 # This is defined in the abstract base, but we can do it much more cheaply. |
| 609 def clear(self): | 623 def clear(self): |
| 610 self._values.clear() | 624 self._values.clear() |
| 611 self._message_listener.Modified() | 625 self._message_listener.Modified() |
| 626 |
| 627 def GetEntryClass(self): |
| 628 return self._entry_descriptor._concrete_class |
| OLD | NEW |