Skip to content

gh-119664: Remove deprecated co_lnotab #119665

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Lib/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,6 @@ def iscode(object):
co_freevars tuple of names of free variables
co_posonlyargcount number of positional only arguments
co_kwonlyargcount number of keyword only arguments (not including ** arg)
co_lnotab encoded mapping of line numbers to bytecode indices
co_name name with which this code object was defined
co_names tuple of names other than arguments and function locals
co_nlocals number of local variables
Expand Down Expand Up @@ -1681,7 +1680,7 @@ def getframeinfo(frame, context=1):

def getlineno(frame):
"""Get the line number from a frame object, allowing for optimization."""
# FrameType.f_lineno is now a descriptor that grovels co_lnotab
# FrameType.f_lineno is a descriptor that grovels co_lines
return frame.f_lineno

_FrameInfo = namedtuple('_FrameInfo', ('frame',) + Traceback._fields)
Expand Down
76 changes: 0 additions & 76 deletions Lib/test/clinic.test.c
Original file line number Diff line number Diff line change
Expand Up @@ -3818,82 +3818,6 @@ test_posonly_opt_keywords_opt_kwonly_opt_impl(PyObject *module, PyObject *a,
PyObject *f)
/*[clinic end generated code: output=07d8acc04558a5a0 input=9914857713c5bbf8]*/

/*[clinic input]
test_keyword_only_parameter


*
co_lnotab: PyBytesObject(c_default="(PyBytesObject *)self->co_lnotab") = None

[clinic start generated code]*/

PyDoc_STRVAR(test_keyword_only_parameter__doc__,
"test_keyword_only_parameter($module, /, *, co_lnotab=None)\n"
"--\n"
"\n");

#define TEST_KEYWORD_ONLY_PARAMETER_METHODDEF \
{"test_keyword_only_parameter", _PyCFunction_CAST(test_keyword_only_parameter), METH_FASTCALL|METH_KEYWORDS, test_keyword_only_parameter__doc__},

static PyObject *
test_keyword_only_parameter_impl(PyObject *module, PyBytesObject *co_lnotab);

static PyObject *
test_keyword_only_parameter(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)

#define NUM_KEYWORDS 1
static struct {
PyGC_Head _this_is_not_used;
PyObject_VAR_HEAD
PyObject *ob_item[NUM_KEYWORDS];
} _kwtuple = {
.ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
.ob_item = { &_Py_ID(co_lnotab), },
};
#undef NUM_KEYWORDS
#define KWTUPLE (&_kwtuple.ob_base.ob_base)

#else // !Py_BUILD_CORE
# define KWTUPLE NULL
#endif // !Py_BUILD_CORE

static const char * const _keywords[] = {"co_lnotab", NULL};
static _PyArg_Parser _parser = {
.keywords = _keywords,
.fname = "test_keyword_only_parameter",
.kwtuple = KWTUPLE,
};
#undef KWTUPLE
PyObject *argsbuf[1];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
PyBytesObject *co_lnotab = (PyBytesObject *)self->co_lnotab;

args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf);
if (!args) {
goto exit;
}
if (!noptargs) {
goto skip_optional_kwonly;
}
if (!PyBytes_Check(args[0])) {
_PyArg_BadArgument("test_keyword_only_parameter", "argument 'co_lnotab'", "bytes", args[0]);
goto exit;
}
co_lnotab = (PyBytesObject *)args[0];
skip_optional_kwonly:
return_value = test_keyword_only_parameter_impl(module, co_lnotab);

exit:
return return_value;
}

static PyObject *
test_keyword_only_parameter_impl(PyObject *module, PyBytesObject *co_lnotab)
/*[clinic end generated code: output=b12fe2e515a62603 input=303df5046c7e37a3]*/


/*[clinic input]
output push
Expand Down
7 changes: 0 additions & 7 deletions Lib/test/test_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,13 +348,6 @@ def func():
new_code = code = func.__code__.replace(co_linetable=b'')
self.assertEqual(list(new_code.co_lines()), [])

def test_co_lnotab_is_deprecated(self): # TODO: remove in 3.14
def func():
pass

with self.assertWarns(DeprecationWarning):
func.__code__.co_lnotab

def test_invalid_bytecode(self):
def foo():
pass
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_peepholer.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def check_jump_targets(self, code):
f'jumps to {tgt.opname} at {tgt.offset}')

def check_lnotab(self, code):
"Check that the lnotab byte offsets are sensible."
"Check that the linetable byte offsets are sensible."
code = dis._get_code_object(code)
lnotab = list(dis.findlinestarts(code))
# Don't bother checking if the line info is sensible, because
Expand All @@ -66,7 +66,7 @@ def check_lnotab(self, code):
self.assertGreaterEqual(min_bytecode, 0)
self.assertLess(max_bytecode, len(code.co_code))
# This could conceivably test more (and probably should, as there
# aren't very many tests of lnotab), if peepholer wasn't scheduled
# aren't very many tests of linetable), if peepholer wasn't scheduled
# to be replaced anyway.

def test_unot(self):
Expand Down
83 changes: 0 additions & 83 deletions Objects/codeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1196,77 +1196,6 @@ _PyLineTable_NextAddressRange(PyCodeAddressRange *range)
return 1;
}

static int
emit_pair(PyObject **bytes, int *offset, int a, int b)
{
Py_ssize_t len = PyBytes_GET_SIZE(*bytes);
if (*offset + 2 >= len) {
if (_PyBytes_Resize(bytes, len * 2) < 0)
return 0;
}
unsigned char *lnotab = (unsigned char *) PyBytes_AS_STRING(*bytes);
lnotab += *offset;
*lnotab++ = a;
*lnotab++ = b;
*offset += 2;
return 1;
}

static int
emit_delta(PyObject **bytes, int bdelta, int ldelta, int *offset)
{
while (bdelta > 255) {
if (!emit_pair(bytes, offset, 255, 0)) {
return 0;
}
bdelta -= 255;
}
while (ldelta > 127) {
if (!emit_pair(bytes, offset, bdelta, 127)) {
return 0;
}
bdelta = 0;
ldelta -= 127;
}
while (ldelta < -128) {
if (!emit_pair(bytes, offset, bdelta, -128)) {
return 0;
}
bdelta = 0;
ldelta += 128;
}
return emit_pair(bytes, offset, bdelta, ldelta);
}

static PyObject *
decode_linetable(PyCodeObject *code)
{
PyCodeAddressRange bounds;
PyObject *bytes;
int table_offset = 0;
int code_offset = 0;
int line = code->co_firstlineno;
bytes = PyBytes_FromStringAndSize(NULL, 64);
if (bytes == NULL) {
return NULL;
}
_PyCode_InitAddressRange(code, &bounds);
while (_PyLineTable_NextAddressRange(&bounds)) {
if (bounds.opaque.computed_line != line) {
int bdelta = bounds.ar_start - code_offset;
int ldelta = bounds.opaque.computed_line - line;
if (!emit_delta(&bytes, bdelta, ldelta, &table_offset)) {
Py_DECREF(bytes);
return NULL;
}
code_offset = bounds.ar_start;
line = bounds.opaque.computed_line;
}
}
_PyBytes_Resize(&bytes, table_offset);
return bytes;
}


typedef struct {
PyObject_HEAD
Expand Down Expand Up @@ -2088,17 +2017,6 @@ static PyMemberDef code_memberlist[] = {
};


static PyObject *
code_getlnotab(PyCodeObject *code, void *closure)
{
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"co_lnotab is deprecated, use co_lines instead.",
1) < 0) {
return NULL;
}
return decode_linetable(code);
}

static PyObject *
code_getvarnames(PyCodeObject *code, void *closure)
{
Expand Down Expand Up @@ -2131,7 +2049,6 @@ code_getcode(PyCodeObject *code, void *closure)
}

static PyGetSetDef code_getsetlist[] = {
{"co_lnotab", (getter)code_getlnotab, NULL, NULL},
{"_co_code_adaptive", (getter)code_getcodeadaptive, NULL, NULL},
// The following old names are kept for backward compatibility.
{"co_varnames", (getter)code_getvarnames, NULL, NULL},
Expand Down
2 changes: 1 addition & 1 deletion Python/assemble.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ write_instr(_Py_CODEUNIT *codestr, instruction *instr, int ilen)

/* assemble_emit_instr()
Extend the bytecode with a new instruction.
Update lnotab if necessary.
Update linetable if necessary.
*/

static int
Expand Down
2 changes: 1 addition & 1 deletion Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -7942,7 +7942,7 @@ _PyCompile_Assemble(_PyCompile_CodeUnitMetadata *umd, PyObject *filename,
}


/* Retained for API compatibility.
/* Retained for API compatibility (co_lnotab is removed since 3.14).
* Optimization is now done in _PyCfg_OptimizeCodeUnit */

PyObject *
Expand Down
Loading