JSON schema arrays with uniqueItems=True creates a model using Python sets which are not serializable by default

Đang mở
#259 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
42/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
python
Lĩnh vực
devtools

Hướng nghiên cứu

Bắt đầu với model AccessControl được tạo và lần theo cách một model được trả về trong một ProgressEvent thông qua quá trình tuần tự hóa JSON của Python. Tái hiện lỗi với schema uniqueItems được cung cấp, sau đó xác minh rằng việc trả về một model chứa các giá trị AbstractSet được tuần tự hóa thành công mà không cần chuyển đổi set sang list thủ công.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

When an definition in the JSON schema is an array with uniqueItems set to True, CFN generates a model with that attribute typed as an AbstractSet (or Python set in real terms) to guarantee that the items are unique. However the JSON module by default does not serialize sets and when the model is returned from the handler it raises an exception when trying to do so.

In order for the model to be returned I need to convert every set to a list in the model so it can be serialized back into JSON.

For example JSON Schema with the following definition:

"AccessControl": {
    "type": "object",
    "properties": {
        "Producers": {
            "type": "array",
            "uniqueItems": true,
            "insertionOrder": false,
            "items": { "type": "string" }  
        },
        "Consumers": {
            "type": "array",
            "uniqueItems": true,
            "insertionOrder": false,
            "items": { "type": "string" }  
        }
    },
    "required": [ "Producers", "Consumers" ],
    "additionalProperties": false
}

Generates a model with the following class

@dataclass
class AccessControl(BaseModel):
    Producers: Optional[AbstractSet[str]]
    Consumers: Optional[AbstractSet[str]]

    @classmethod
    def _deserialize(
        cls: Type["_AccessControl"],
        json_data: Optional[Mapping[str, Any]],
    ) -> Optional["_AccessControl"]:
        if not json_data:
            return None
        return cls(
            Producers=set_or_none(json_data.get("Producers")),
            Consumers=set_or_none(json_data.get("Consumers")),
        )

If the incoming model to the handler is populated and returned in a ProgressEvent the handler fails with an exception trying to serialize a set which it cant do by default. In order to return the model I have to convert every set to a list ie model.AccessControl.Producers = list(model.AccessControl.Producers). This can be tedious if there are multiple exit points in the handler and so should be handled by the model or by adding a set serializer to JSON.

Ngôn ngữ chính
Python
Star
107
Fork
46
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của aws-cloudformation/cloudformation-cli-python-plugin

Tất cả issue của aws-cloudformation/cloudformation-cli-python-plugin

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.