@@ -67,49 +67,66 @@ def _check_attribute(self, prev: SemanticAttribute, problems: list[Problem]):
6767 problems .append (Problem ("attribute" , prev .fqn , "was removed" ))
6868 return
6969
70+ self ._check_stability (
71+ prev .stability , cur .stability , "attribute" , prev .fqn , problems
72+ )
7073 if prev .stability == StabilityLevel .STABLE :
71- if cur .stability != prev .stability :
74+ self ._check_attribute_type (prev , cur , problems )
75+
76+ if (
77+ isinstance (prev .attr_type , EnumAttributeType )
78+ and
79+ # this makes mypy happy, we already checked that type is the same for stable attributes
80+ isinstance (cur .attr_type , EnumAttributeType )
81+ ):
82+ for member in prev .attr_type .members :
83+ self ._check_member (prev .fqn , member , cur .attr_type .members , problems )
84+
85+ def _check_stability (
86+ self ,
87+ prev : StabilityLevel ,
88+ cur : StabilityLevel ,
89+ signal : str ,
90+ fqn : str ,
91+ problems : list [Problem ],
92+ ):
93+ if prev == StabilityLevel .STABLE and cur != prev :
94+ problems .append (
95+ Problem (signal , fqn , f"stability changed from '{ prev } ' to '{ cur } '" )
96+ )
97+
98+ def _check_attribute_type (
99+ self , prev : SemanticAttribute , cur : SemanticAttribute , problems : list [Problem ]
100+ ):
101+ if isinstance (prev .attr_type , EnumAttributeType ):
102+ if not isinstance (cur .attr_type , EnumAttributeType ):
72103 problems .append (
73104 Problem (
74105 "attribute" ,
75106 prev .fqn ,
76- f"stability changed from '{ prev .stability } ' to '{ cur .stability } '" ,
107+ f"type changed from '{ prev .attr_type } ' to '{ cur .attr_type } '" ,
77108 )
78109 )
79-
80- if isinstance (prev .attr_type , EnumAttributeType ):
81- if not isinstance (cur .attr_type , EnumAttributeType ):
110+ else :
111+ # enum type change inevitably causes some values to be removed
112+ # which will be reported in _check_member method as well.
113+ # keeping this check to provide more detailed error message
114+ if cur .attr_type .enum_type != prev .attr_type .enum_type :
82115 problems .append (
83116 Problem (
84117 "attribute" ,
85118 prev .fqn ,
86- f"type changed from '{ prev .attr_type } ' to '{ cur .attr_type } '" ,
119+ f"enum type changed from '{ prev .attr_type . enum_type } ' to '{ cur .attr_type . enum_type } '" ,
87120 )
88121 )
89- else :
90- # enum type change inevitably causes some values to be removed
91- # which will be reported in _check_member method as well.
92- # keeping this check to provide more detailed error message
93- if cur .attr_type .enum_type != prev .attr_type .enum_type :
94- problems .append (
95- Problem (
96- "attribute" ,
97- prev .fqn ,
98- f"enum type changed from '{ prev .attr_type .enum_type } ' to '{ cur .attr_type .enum_type } '" ,
99- )
100- )
101- for member in prev .attr_type .members :
102- self ._check_member (
103- prev .fqn , member , cur .attr_type .members , problems
104- )
105- elif cur .attr_type != prev .attr_type :
106- problems .append (
107- Problem (
108- "attribute" ,
109- prev .fqn ,
110- f"type changed from '{ prev .attr_type } ' to '{ cur .attr_type } '" ,
111- )
122+ elif cur .attr_type != prev .attr_type :
123+ problems .append (
124+ Problem (
125+ "attribute" ,
126+ prev .fqn ,
127+ f"type changed from '{ prev .attr_type } ' to '{ cur .attr_type } '" ,
112128 )
129+ )
113130
114131 def _check_member (
115132 self ,
@@ -118,8 +135,22 @@ def _check_member(
118135 members : list [EnumMember ],
119136 problems : list [Problem ],
120137 ):
138+ found = False
121139 for member in members :
122140 if prev .member_id == member .member_id :
141+ found = True
142+ if prev .stability != StabilityLevel .STABLE :
143+ # we allow stability and value changes for non-stable members
144+ break
145+
146+ self ._check_stability (
147+ prev .stability ,
148+ member .stability ,
149+ "enum attribute member" ,
150+ f"{ fqn } .{ prev .member_id } " ,
151+ problems ,
152+ )
153+
123154 if prev .value != member .value :
124155 member_value = (
125156 f'"{ member .value } "'
@@ -133,10 +164,12 @@ def _check_member(
133164 f"value changed from '{ prev .value } ' to '{ member_value } '" ,
134165 )
135166 )
136- return
137- problems .append (
138- Problem ("enum attribute member" , f"{ fqn } .{ prev .member_id } " , "was removed" )
139- )
167+ if not found :
168+ problems .append (
169+ Problem (
170+ "enum attribute member" , f"{ fqn } .{ prev .member_id } " , "was removed"
171+ )
172+ )
140173
141174 def _check_metric (self , prev : MetricSemanticConvention , problems : list [Problem ]):
142175 for cur in self .current_semconv .models .values ():
@@ -145,14 +178,13 @@ def _check_metric(self, prev: MetricSemanticConvention, problems: list[Problem])
145178 and cur .metric_name == prev .metric_name
146179 ):
147180 if prev .stability == StabilityLevel .STABLE :
148- if cur .stability != prev .stability :
149- problems .append (
150- Problem (
151- "metric" ,
152- prev .metric_name ,
153- f"stability changed from '{ prev .stability } ' to '{ cur .stability } '" ,
154- )
155- )
181+ self ._check_stability (
182+ prev .stability ,
183+ cur .stability ,
184+ "metric" ,
185+ prev .metric_name ,
186+ problems ,
187+ )
156188 if cur .unit != prev .unit :
157189 problems .append (
158190 Problem (
0 commit comments