@@ -104,6 +104,7 @@ def __init__(
104
104
info : TypeInfo ,
105
105
kw_only : bool ,
106
106
is_neither_frozen_nor_nonfrozen : bool ,
107
+ api : SemanticAnalyzerPluginInterface ,
107
108
) -> None :
108
109
self .name = name
109
110
self .alias = alias
@@ -116,6 +117,7 @@ def __init__(
116
117
self .info = info
117
118
self .kw_only = kw_only
118
119
self .is_neither_frozen_nor_nonfrozen = is_neither_frozen_nor_nonfrozen
120
+ self ._api = api
119
121
120
122
def to_argument (self , current_info : TypeInfo ) -> Argument :
121
123
arg_kind = ARG_POS
@@ -138,7 +140,10 @@ def expand_type(self, current_info: TypeInfo) -> Optional[Type]:
138
140
# however this plugin is called very late, so all types should be fully ready.
139
141
# Also, it is tricky to avoid eager expansion of Self types here (e.g. because
140
142
# we serialize attributes).
141
- return expand_type (self .type , {self .info .self_type .id : fill_typevars (current_info )})
143
+ with state .strict_optional_set (self ._api .options .strict_optional ):
144
+ return expand_type (
145
+ self .type , {self .info .self_type .id : fill_typevars (current_info )}
146
+ )
142
147
return self .type
143
148
144
149
def to_var (self , current_info : TypeInfo ) -> Var :
@@ -165,13 +170,14 @@ def deserialize(
165
170
) -> DataclassAttribute :
166
171
data = data .copy ()
167
172
typ = deserialize_and_fixup_type (data .pop ("type" ), api )
168
- return cls (type = typ , info = info , ** data )
173
+ return cls (type = typ , info = info , ** data , api = api )
169
174
170
175
def expand_typevar_from_subtype (self , sub_type : TypeInfo ) -> None :
171
176
"""Expands type vars in the context of a subtype when an attribute is inherited
172
177
from a generic super type."""
173
178
if self .type is not None :
174
- self .type = map_type_from_supertype (self .type , sub_type , self .info )
179
+ with state .strict_optional_set (self ._api .options .strict_optional ):
180
+ self .type = map_type_from_supertype (self .type , sub_type , self .info )
175
181
176
182
177
183
class DataclassTransformer :
@@ -230,12 +236,11 @@ def transform(self) -> bool:
230
236
and ("__init__" not in info .names or info .names ["__init__" ].plugin_generated )
231
237
and attributes
232
238
):
233
- with state .strict_optional_set (self ._api .options .strict_optional ):
234
- args = [
235
- attr .to_argument (info )
236
- for attr in attributes
237
- if attr .is_in_init and not self ._is_kw_only_type (attr .type )
238
- ]
239
+ args = [
240
+ attr .to_argument (info )
241
+ for attr in attributes
242
+ if attr .is_in_init and not self ._is_kw_only_type (attr .type )
243
+ ]
239
244
240
245
if info .fallback_to_any :
241
246
# Make positional args optional since we don't know their order.
@@ -355,8 +360,7 @@ def transform(self) -> bool:
355
360
self ._add_dataclass_fields_magic_attribute ()
356
361
357
362
if self ._spec is _TRANSFORM_SPEC_FOR_DATACLASSES :
358
- with state .strict_optional_set (self ._api .options .strict_optional ):
359
- self ._add_internal_replace_method (attributes )
363
+ self ._add_internal_replace_method (attributes )
360
364
if "__post_init__" in info .names :
361
365
self ._add_internal_post_init_method (attributes )
362
366
@@ -546,8 +550,7 @@ def collect_attributes(self) -> list[DataclassAttribute] | None:
546
550
# TODO: We shouldn't be performing type operations during the main
547
551
# semantic analysis pass, since some TypeInfo attributes might
548
552
# still be in flux. This should be performed in a later phase.
549
- with state .strict_optional_set (self ._api .options .strict_optional ):
550
- attr .expand_typevar_from_subtype (cls .info )
553
+ attr .expand_typevar_from_subtype (cls .info )
551
554
found_attrs [name ] = attr
552
555
553
556
sym_node = cls .info .names .get (name )
@@ -693,6 +696,7 @@ def collect_attributes(self) -> list[DataclassAttribute] | None:
693
696
is_neither_frozen_nor_nonfrozen = _has_direct_dataclass_transform_metaclass (
694
697
cls .info
695
698
),
699
+ api = self ._api ,
696
700
)
697
701
698
702
all_attrs = list (found_attrs .values ())
0 commit comments