Resolves shape references.
| 747 | |
| 748 | |
| 749 | class ShapeResolver: |
| 750 | """Resolves shape references.""" |
| 751 | |
| 752 | # Any type not in this mapping will default to the Shape class. |
| 753 | SHAPE_CLASSES = { |
| 754 | 'structure': StructureShape, |
| 755 | 'list': ListShape, |
| 756 | 'map': MapShape, |
| 757 | 'string': StringShape, |
| 758 | } |
| 759 | |
| 760 | def __init__(self, shape_map): |
| 761 | self._shape_map = shape_map |
| 762 | self._shape_cache = {} |
| 763 | |
| 764 | def get_shape_by_name(self, shape_name, member_traits=None): |
| 765 | try: |
| 766 | shape_model = self._shape_map[shape_name] |
| 767 | except KeyError: |
| 768 | raise NoShapeFoundError(shape_name) |
| 769 | try: |
| 770 | shape_cls = self.SHAPE_CLASSES.get(shape_model['type'], Shape) |
| 771 | except KeyError: |
| 772 | raise InvalidShapeError( |
| 773 | f"Shape is missing required key 'type': {shape_model}" |
| 774 | ) |
| 775 | if member_traits: |
| 776 | shape_model = shape_model.copy() |
| 777 | shape_model.update(member_traits) |
| 778 | result = shape_cls(shape_name, shape_model, self) |
| 779 | return result |
| 780 | |
| 781 | def resolve_shape_ref(self, shape_ref): |
| 782 | # A shape_ref is a dict that has a 'shape' key that |
| 783 | # refers to a shape name as well as any additional |
| 784 | # member traits that are then merged over the shape |
| 785 | # definition. For example: |
| 786 | # {"shape": "StringType", "locationName": "Foobar"} |
| 787 | if len(shape_ref) == 1 and 'shape' in shape_ref: |
| 788 | # It's just a shape ref with no member traits, we can avoid |
| 789 | # a .copy(). This is the common case so it's specifically |
| 790 | # called out here. |
| 791 | return self.get_shape_by_name(shape_ref['shape']) |
| 792 | else: |
| 793 | member_traits = shape_ref.copy() |
| 794 | try: |
| 795 | shape_name = member_traits.pop('shape') |
| 796 | except KeyError: |
| 797 | raise InvalidShapeReferenceError( |
| 798 | f"Invalid model, missing shape reference: {shape_ref}" |
| 799 | ) |
| 800 | return self.get_shape_by_name(shape_name, member_traits) |
| 801 | |
| 802 | |
| 803 | class UnresolvableShapeMap: |
no outgoing calls