@@ -54,7 +54,7 @@ def __init__(self, attributes: dict[str, Any], data: Optional[dict] = None) -> N
5454 :raises ValueError: If any of the required attributes are missing or have invalid values.
5555 :raises TypeError: If any of the attributes have invalid types.
5656 """
57- self ._validate_attribute (attributes )
57+ self ._validate_attribute (attributes = attributes )
5858 self ._attributes : dict [str , Any ] = attributes
5959 self ._data : Optional [dict ] = data
6060
@@ -66,9 +66,9 @@ def _validate_attribute(attributes: dict[str, Any]) -> None:
6666 See https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md#required-attributes
6767 """
6868 errors : dict [str , list [BaseCloudEventException ]] = defaultdict (list )
69- errors .update (CloudEvent ._validate_required_attributes (attributes ))
70- errors .update (CloudEvent ._validate_optional_attributes (attributes ))
71- errors .update (CloudEvent ._validate_extension_attributes (attributes ))
69+ errors .update (CloudEvent ._validate_required_attributes (attributes = attributes ))
70+ errors .update (CloudEvent ._validate_optional_attributes (attributes = attributes ))
71+ errors .update (CloudEvent ._validate_extension_attributes (attributes = attributes ))
7272 if errors :
7373 raise CloudEventValidationError (dict (errors ))
7474
@@ -88,33 +88,46 @@ def _validate_required_attributes(
8888 errors ["id" ].append (MissingRequiredAttributeError (attribute_name = "id" ))
8989 if attributes .get ("id" ) is None :
9090 errors ["id" ].append (
91- InvalidAttributeValueError ("id" , "Attribute 'id' must not be None" )
91+ InvalidAttributeValueError (
92+ attribute_name = "id" , msg = "Attribute 'id' must not be None"
93+ )
9294 )
9395 if not isinstance (attributes .get ("id" ), str ):
94- errors ["id" ].append (InvalidAttributeTypeError ("id" , str ))
96+ errors ["id" ].append (
97+ InvalidAttributeTypeError (attribute_name = "id" , expected_type = str )
98+ )
9599
96100 if "source" not in attributes :
97101 errors ["source" ].append (
98102 MissingRequiredAttributeError (attribute_name = "source" )
99103 )
100104 if not isinstance (attributes .get ("source" ), str ):
101- errors ["source" ].append (InvalidAttributeTypeError ("source" , str ))
105+ errors ["source" ].append (
106+ InvalidAttributeTypeError (attribute_name = "source" , expected_type = str )
107+ )
102108
103109 if "type" not in attributes :
104110 errors ["type" ].append (MissingRequiredAttributeError (attribute_name = "type" ))
105111 if not isinstance (attributes .get ("type" ), str ):
106- errors ["type" ].append (InvalidAttributeTypeError ("type" , str ))
112+ errors ["type" ].append (
113+ InvalidAttributeTypeError (attribute_name = "type" , expected_type = str )
114+ )
107115
108116 if "specversion" not in attributes :
109117 errors ["specversion" ].append (
110118 MissingRequiredAttributeError (attribute_name = "specversion" )
111119 )
112120 if not isinstance (attributes .get ("specversion" ), str ):
113- errors ["specversion" ].append (InvalidAttributeTypeError ("specversion" , str ))
121+ errors ["specversion" ].append (
122+ InvalidAttributeTypeError (
123+ attribute_name = "specversion" , expected_type = str
124+ )
125+ )
114126 if attributes .get ("specversion" ) != "1.0" :
115127 errors ["specversion" ].append (
116128 InvalidAttributeValueError (
117- "specversion" , "Attribute 'specversion' must be '1.0'"
129+ attribute_name = "specversion" ,
130+ msg = "Attribute 'specversion' must be '1.0'" ,
118131 )
119132 )
120133 return errors
@@ -133,43 +146,58 @@ def _validate_optional_attributes(
133146
134147 if "time" in attributes :
135148 if not isinstance (attributes ["time" ], datetime ):
136- errors ["time" ].append (InvalidAttributeTypeError ("time" , datetime ))
149+ errors ["time" ].append (
150+ InvalidAttributeTypeError (
151+ attribute_name = "time" , expected_type = datetime
152+ )
153+ )
137154 if hasattr (attributes ["time" ], "tzinfo" ) and not attributes ["time" ].tzinfo :
138155 errors ["time" ].append (
139156 InvalidAttributeValueError (
140- "time" , "Attribute 'time' must be timezone aware"
157+ attribute_name = "time" ,
158+ msg = "Attribute 'time' must be timezone aware" ,
141159 )
142160 )
143161 if "subject" in attributes :
144162 if not isinstance (attributes ["subject" ], str ):
145- errors ["subject" ].append (InvalidAttributeTypeError ("subject" , str ))
163+ errors ["subject" ].append (
164+ InvalidAttributeTypeError (
165+ attribute_name = "subject" , expected_type = str
166+ )
167+ )
146168 if not attributes ["subject" ]:
147169 errors ["subject" ].append (
148170 InvalidAttributeValueError (
149- "subject" , "Attribute 'subject' must not be empty"
171+ attribute_name = "subject" ,
172+ msg = "Attribute 'subject' must not be empty" ,
150173 )
151174 )
152175 if "datacontenttype" in attributes :
153176 if not isinstance (attributes ["datacontenttype" ], str ):
154177 errors ["datacontenttype" ].append (
155- InvalidAttributeTypeError ("datacontenttype" , str )
178+ InvalidAttributeTypeError (
179+ attribute_name = "datacontenttype" , expected_type = str
180+ )
156181 )
157182 if not attributes ["datacontenttype" ]:
158183 errors ["datacontenttype" ].append (
159184 InvalidAttributeValueError (
160- "datacontenttype" ,
161- "Attribute 'datacontenttype' must not be empty" ,
185+ attribute_name = "datacontenttype" ,
186+ msg = "Attribute 'datacontenttype' must not be empty" ,
162187 )
163188 )
164189 if "dataschema" in attributes :
165190 if not isinstance (attributes ["dataschema" ], str ):
166191 errors ["dataschema" ].append (
167- InvalidAttributeTypeError ("dataschema" , str )
192+ InvalidAttributeTypeError (
193+ attribute_name = "dataschema" , expected_type = str
194+ )
168195 )
169196 if not attributes ["dataschema" ]:
170197 errors ["dataschema" ].append (
171198 InvalidAttributeValueError (
172- "dataschema" , "Attribute 'dataschema' must not be empty"
199+ attribute_name = "dataschema" ,
200+ msg = "Attribute 'dataschema' must not be empty" ,
173201 )
174202 )
175203 return errors
@@ -194,22 +222,22 @@ def _validate_extension_attributes(
194222 if extension_attribute == "data" :
195223 errors [extension_attribute ].append (
196224 CustomExtensionAttributeError (
197- extension_attribute ,
198- "Extension attribute 'data' is reserved and must not be used" ,
225+ attribute_name = extension_attribute ,
226+ msg = "Extension attribute 'data' is reserved and must not be used" ,
199227 )
200228 )
201229 if not (1 <= len (extension_attribute ) <= 20 ):
202230 errors [extension_attribute ].append (
203231 CustomExtensionAttributeError (
204- extension_attribute ,
205- f"Extension attribute '{ extension_attribute } ' should be between 1 and 20 characters long" ,
232+ attribute_name = extension_attribute ,
233+ msg = f"Extension attribute '{ extension_attribute } ' should be between 1 and 20 characters long" ,
206234 )
207235 )
208236 if not re .match (r"^[a-z0-9]+$" , extension_attribute ):
209237 errors [extension_attribute ].append (
210238 CustomExtensionAttributeError (
211- extension_attribute ,
212- f"Extension attribute '{ extension_attribute } ' should only contain lowercase letters and numbers" ,
239+ attribute_name = extension_attribute ,
240+ msg = f"Extension attribute '{ extension_attribute } ' should only contain lowercase letters and numbers" ,
213241 )
214242 )
215243 return errors
0 commit comments