MCPcopy Create free account
hub / github.com/python/mypy / find_always_defined_attributes

Function find_always_defined_attributes

mypyc/analysis/attrdefined.py:192–239  ·  view source on GitHub ↗

Find attributes that are always initialized in some basic blocks. The analysis results are expected to be up-to-date for the blocks. Return a set of always defined attributes.

(
    blocks: list[BasicBlock],
    self_reg: Register,
    all_attrs: set[str],
    maybe_defined: AnalysisResult[str],
    maybe_undefined: AnalysisResult[str],
    dirty: AnalysisResult[None],
)

Source from the content-addressed store, hash-verified

190
191
192def find_always_defined_attributes(
193 blocks: list[BasicBlock],
194 self_reg: Register,
195 all_attrs: set[str],
196 maybe_defined: AnalysisResult[str],
197 maybe_undefined: AnalysisResult[str],
198 dirty: AnalysisResult[None],
199) -> set[str]:
200 """Find attributes that are always initialized in some basic blocks.
201
202 The analysis results are expected to be up-to-date for the blocks.
203
204 Return a set of always defined attributes.
205 """
206 attrs = all_attrs.copy()
207 for block in blocks:
208 for i, op in enumerate(block.ops):
209 # If an attribute we *read* may be undefined, it isn't always defined.
210 if isinstance(op, GetAttr) and op.obj is self_reg:
211 if op.attr in maybe_undefined.before[block, i]:
212 attrs.discard(op.attr)
213 # If an attribute we *set* may be sometimes undefined and
214 # sometimes defined, don't consider it always defined. Unlike
215 # the get case, it's fine for the attribute to be undefined.
216 # The set operation will then be treated as initialization.
217 if isinstance(op, SetAttr) and op.obj is self_reg:
218 if (
219 op.attr in maybe_undefined.before[block, i]
220 and op.attr in maybe_defined.before[block, i]
221 ):
222 attrs.discard(op.attr)
223 # Treat an op that might run arbitrary code as an "exit"
224 # in terms of the analysis -- we can't do any inference
225 # afterwards reliably.
226 if dirty.after[block, i]:
227 if not dirty.before[block, i]:
228 attrs = attrs & (
229 maybe_defined.after[block, i] - maybe_undefined.after[block, i]
230 )
231 break
232 if isinstance(op, ControlOp):
233 for target in op.targets():
234 # Gotos/branches can also be "exits".
235 if not dirty.after[block, i] and dirty.before[target, 0]:
236 attrs = attrs & (
237 maybe_defined.after[target, 0] - maybe_undefined.after[target, 0]
238 )
239 return attrs
240
241
242def find_sometimes_defined_attributes(

Callers 1

Calls 5

enumerateFunction · 0.85
isinstanceFunction · 0.85
discardMethod · 0.80
copyMethod · 0.45
targetsMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…