Skip to content

Commit fba56f5

Browse files
co._get_localsplusnames() -> co._varname_from_oparg()
1 parent 13fe60d commit fba56f5

File tree

3 files changed

+70
-39
lines changed

3 files changed

+70
-39
lines changed

Lib/dis.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ def get_instructions(x, *, first_line=None):
279279
else:
280280
line_offset = 0
281281
return _get_instructions_bytes(co.co_code,
282-
co._get_localsplusnames(), co.co_nlocals,
282+
co._varname_from_oparg,
283283
co.co_names, co.co_consts,
284284
linestarts, line_offset)
285285

@@ -295,16 +295,16 @@ def _get_const_info(const_index, const_list):
295295
argval = const_list[const_index]
296296
return argval, repr(argval)
297297

298-
def _get_name_info(name_index, name_list):
298+
def _get_name_info(name_index, get_name, **extrainfo):
299299
"""Helper to get optional details about named references
300300
301301
Returns the dereferenced name as both value and repr if the name
302302
list is defined.
303303
Otherwise returns the name index and its repr().
304304
"""
305305
argval = name_index
306-
if name_list is not None:
307-
argval = name_list[name_index]
306+
if get_name is not None:
307+
argval = get_name(name_index, **extrainfo)
308308
argrepr = argval
309309
else:
310310
argrepr = repr(argval)
@@ -336,7 +336,7 @@ def parse_exception_table(code):
336336
except StopIteration:
337337
return entries
338338

339-
def _get_instructions_bytes(code, localsplusnames=None, nlocals=0,
339+
def _get_instructions_bytes(code, varname_from_oparg=None,
340340
names=None, constants=None,
341341
linestarts=None, line_offset=0,
342342
exception_entries=()):
@@ -348,6 +348,7 @@ def _get_instructions_bytes(code, localsplusnames=None, nlocals=0,
348348
arguments.
349349
350350
"""
351+
get_name = None if names is None else names.__getitem__
351352
labels = set(findlabels(code))
352353
for start, end, target, _, _ in exception_entries:
353354
for i in range(start, end):
@@ -370,20 +371,21 @@ def _get_instructions_bytes(code, localsplusnames=None, nlocals=0,
370371
if op in hasconst:
371372
argval, argrepr = _get_const_info(arg, constants)
372373
elif op in hasname:
373-
argval, argrepr = _get_name_info(arg, names)
374+
argval, argrepr = _get_name_info(arg, get_name)
374375
elif op in hasjabs:
375376
argval = arg*2
376377
argrepr = "to " + repr(argval)
377378
elif op in hasjrel:
378379
argval = offset + 2 + arg*2
379380
argrepr = "to " + repr(argval)
380381
elif op in haslocal:
381-
argval, argrepr = _get_name_info(arg, localsplusnames)
382+
argval, argrepr = _get_name_info(arg, varname_from_oparg)
382383
elif op in hascompare:
383384
argval = cmp_op[arg]
384385
argrepr = argval
385386
elif op in hasfree:
386-
argval, argrepr = _get_name_info(arg + nlocals, localsplusnames)
387+
argval, argrepr = _get_name_info(arg, varname_from_oparg,
388+
cell=True)
387389
elif op == FORMAT_VALUE:
388390
argval, argrepr = FORMAT_VALUE_CONVERTERS[arg & 0x3]
389391
argval = (argval, bool(arg & 0x4))
@@ -403,7 +405,7 @@ def disassemble(co, lasti=-1, *, file=None):
403405
linestarts = dict(findlinestarts(co))
404406
exception_entries = parse_exception_table(co)
405407
_disassemble_bytes(co.co_code, lasti,
406-
co._get_localsplusnames(), co.co_nlocals,
408+
co._varname_from_oparg,
407409
co.co_names, co.co_consts, linestarts, file=file,
408410
exception_entries=exception_entries)
409411

@@ -418,7 +420,7 @@ def _disassemble_recursive(co, *, file=None, depth=None):
418420
print("Disassembly of %r:" % (x,), file=file)
419421
_disassemble_recursive(x, file=file, depth=depth)
420422

421-
def _disassemble_bytes(code, lasti=-1, localsplusnames=None, nlocals=0,
423+
def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None,
422424
names=None, constants=None, linestarts=None,
423425
*, file=None, line_offset=0, exception_entries=()):
424426
# Omit the line number column entirely if we have no line number info
@@ -436,7 +438,7 @@ def _disassemble_bytes(code, lasti=-1, localsplusnames=None, nlocals=0,
436438
offset_width = len(str(maxoffset))
437439
else:
438440
offset_width = 4
439-
for instr in _get_instructions_bytes(code, localsplusnames, nlocals, names,
441+
for instr in _get_instructions_bytes(code, varname_from_oparg, names,
440442
constants, linestarts,
441443
line_offset=line_offset, exception_entries=exception_entries):
442444
new_source_line = (show_lineno and
@@ -527,7 +529,7 @@ def __init__(self, x, *, first_line=None, current_offset=None):
527529
def __iter__(self):
528530
co = self.codeobj
529531
return _get_instructions_bytes(co.co_code,
530-
co._get_localsplusnames(), co.co_nlocals,
532+
co._varname_from_oparg,
531533
co.co_names, co.co_consts,
532534
self._linestarts,
533535
line_offset=self._line_offset,
@@ -557,8 +559,7 @@ def dis(self):
557559
offset = -1
558560
with io.StringIO() as output:
559561
_disassemble_bytes(co.co_code,
560-
localsplusnames=co._get_localsplusnames(),
561-
nlocals=co.co_nlocals,
562+
varname_from_oparg=co._varname_from_oparg,
562563
names=co.co_names, constants=co.co_consts,
563564
linestarts=self._linestarts,
564565
line_offset=self._line_offset,

Objects/clinic/codeobject.c.h

Lines changed: 37 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Objects/codeobject.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,23 +1544,30 @@ code_replace_impl(PyCodeObject *self, int co_argcount,
15441544
}
15451545

15461546
/*[clinic input]
1547-
code._get_localsplusnames
1547+
code._varname_from_oparg
15481548
1549-
(internal-only) Return the "fast locals" names tuple for the code object.
1549+
oparg: int
1550+
*
1551+
cell: bool = False
15501552
1551-
WARNING: this method is for internal use only and may change or go away.
1553+
(internal-only) Return the local variable name for the given oparg.
15521554
1553-
This is the combined list of variable names mapped to the corresponding
1554-
indices in the frame's "fast locals" array. It is effectively the same
1555-
as co_varnames + co_cellvars + co_freevars.
1555+
WARNING: this method is for internal use only and may change or go away.
15561556
[clinic start generated code]*/
15571557

15581558
static PyObject *
1559-
code__get_localsplusnames_impl(PyCodeObject *self)
1560-
/*[clinic end generated code: output=1ba0ba2302737af6 input=4c57e413e404152b]*/
1559+
code__varname_from_oparg_impl(PyCodeObject *self, int oparg, int cell)
1560+
/*[clinic end generated code: output=c7d39c9723692c8f input=2945bb291d3a3118]*/
15611561
{
1562-
Py_INCREF(self->co_localsplusnames);
1563-
return self->co_localsplusnames;
1562+
if (cell) {
1563+
oparg += self->co_nlocals;
1564+
}
1565+
PyObject *name = PyTuple_GetItem(self->co_localsplusnames, oparg);
1566+
if (name == NULL) {
1567+
return NULL;
1568+
}
1569+
Py_INCREF(name);
1570+
return name;
15641571
}
15651572

15661573
/* XXX code objects need to participate in GC? */
@@ -1569,7 +1576,7 @@ static struct PyMethodDef code_methods[] = {
15691576
{"__sizeof__", (PyCFunction)code_sizeof, METH_NOARGS},
15701577
{"co_lines", (PyCFunction)code_linesiterator, METH_NOARGS},
15711578
CODE_REPLACE_METHODDEF
1572-
CODE__GET_LOCALSPLUSNAMES_METHODDEF
1579+
CODE__VARNAME_FROM_OPARG_METHODDEF
15731580
{NULL, NULL} /* sentinel */
15741581
};
15751582

0 commit comments

Comments
 (0)