MCPcopy Index your code
hub / github.com/python/mypy / enum_value_callback

Function enum_value_callback

mypy/plugins/enums.py:160–270  ·  view source on GitHub ↗

This plugin refines the 'value' attribute in enums to refer to the original underlying value. For example, suppose we have the following: class SomeEnum: FOO = A() BAR = B() By default, mypy will infer that 'SomeEnum.FOO.value' and 'SomeEnum.BAR.valu

(ctx: mypy.plugin.AttributeContext)

Source from the content-addressed store, hash-verified

158
159
160def enum_value_callback(ctx: mypy.plugin.AttributeContext) -> Type:
161 """This plugin refines the 'value' attribute in enums to refer to
162 the original underlying value. For example, suppose we have the
163 following:
164
165 class SomeEnum:
166 FOO = A()
167 BAR = B()
168
169 By default, mypy will infer that 'SomeEnum.FOO.value' and
170 'SomeEnum.BAR.value' both are of type 'Any'. This plugin refines
171 this inference so that mypy understands the expressions are
172 actually of types 'A' and 'B' respectively. This better reflects
173 the actual runtime behavior.
174
175 This plugin works simply by looking up the original value assigned
176 to the enum. For example, when this plugin sees 'SomeEnum.BAR.value',
177 it will look up whatever type 'BAR' had in the SomeEnum TypeInfo and
178 use that as the inferred type of the overall expression.
179
180 This plugin assumes that the provided context is an attribute access
181 matching one of the strings found in 'ENUM_VALUE_ACCESS'.
182 """
183 enum_field_name = _extract_underlying_field_name(ctx.type)
184 if enum_field_name is None:
185 # We do not know the enum field name (perhaps it was passed to a
186 # function and we only know that it _is_ a member). All is not lost
187 # however, if we can prove that the all of the enum members have the
188 # same value-type, then it doesn't matter which member was passed in.
189 # The value-type is still known.
190 if isinstance(ctx.type, Instance):
191 info = ctx.type.type
192
193 # As long as mypy doesn't understand attribute creation in __new__,
194 # there is no way to predict the value type if the enum class has a
195 # custom implementation
196 if _implements_new(info):
197 return ctx.default_attr_type
198
199 stnodes = (info.get(name) for name in info.names)
200
201 # Enums _can_ have methods, instance attributes, and `nonmember`s.
202 # Omit methods and attributes created by assigning to self.*
203 # for our value inference.
204 node_types = (
205 get_proper_type(n.type) if n else None
206 for n in stnodes
207 if n is None or not n.implicit
208 )
209 proper_types = [
210 _infer_value_type_with_auto_fallback(ctx, t)
211 for t in node_types
212 if t is None
213 or (not isinstance(t, CallableType) and not is_named_instance(t, "enum.nonmember"))
214 ]
215 underlying_type = _first(proper_types)
216 if underlying_type is None:
217 return ctx.default_attr_type

Callers

nothing calls this directly

Calls 11

get_proper_typeFunction · 0.90
is_named_instanceFunction · 0.90
is_equivalentFunction · 0.90
make_simplified_unionFunction · 0.90
isinstanceFunction · 0.85
_implements_newFunction · 0.85
_firstFunction · 0.85
allFunction · 0.85
getMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…