Skip to content

gh-134690: Removed deprecated codetype.co_lnotab #134691

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion Doc/deprecations/pending-removal-in-3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Pending removal in Python 3.15

* :mod:`types`:

* :class:`types.CodeType`: Accessing :attr:`~codeobject.co_lnotab` was
* :class:`types.CodeType`: Accessing :attr:`!codeobject.co_lnotab` was
deprecated in :pep:`626`
since 3.10 and was planned to be removed in 3.12,
but it only got a proper :exc:`DeprecationWarning` in 3.12.
Expand Down
2 changes: 1 addition & 1 deletion Doc/deprecations/pending-removal-in-future.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ although there is currently no date scheduled for their removal.

* :mod:`codecs`: use :func:`open` instead of :func:`codecs.open`. (:gh:`133038`)

* :attr:`codeobject.co_lnotab`: use the :meth:`codeobject.co_lines` method
* :attr:`!codeobject.co_lnotab`: use the :meth:`codeobject.co_lines` method
instead.

* :mod:`datetime`:
Expand Down
2 changes: 1 addition & 1 deletion Doc/library/dis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ operation is being performed, so the intermediate analysis object isn't useful:

.. versionchanged:: 3.10
The :pep:`626` :meth:`~codeobject.co_lines` method is used instead of the
:attr:`~codeobject.co_firstlineno` and :attr:`~codeobject.co_lnotab`
:attr:`~codeobject.co_firstlineno` and :attr:`!codeobject.co_lnotab`
attributes of the :ref:`code object <code-objects>`.

.. versionchanged:: 3.13
Expand Down
4 changes: 0 additions & 4 deletions Doc/library/inspect.rst
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,6 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
| | | read more :ref:`here |
| | | <inspect-module-co-flags>`|
+-----------------+-------------------+---------------------------+
| | co_lnotab | encoded mapping of line |
| | | numbers to bytecode |
| | | indices |
+-----------------+-------------------+---------------------------+
| | co_freevars | tuple of names of free |
| | | variables (referenced via |
| | | a function's closure) |
Expand Down
9 changes: 0 additions & 9 deletions Doc/reference/datamodel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1415,7 +1415,6 @@ indirectly) to mutable objects.
single: co_filename (code object attribute)
single: co_firstlineno (code object attribute)
single: co_flags (code object attribute)
single: co_lnotab (code object attribute)
single: co_name (code object attribute)
single: co_names (code object attribute)
single: co_nlocals (code object attribute)
Expand Down Expand Up @@ -1488,14 +1487,6 @@ Special read-only attributes
* - .. attribute:: codeobject.co_firstlineno
- The line number of the first line of the function

* - .. attribute:: codeobject.co_lnotab
- A string encoding the mapping from :term:`bytecode` offsets to line
numbers. For details, see the source code of the interpreter.

.. deprecated:: 3.12
This attribute of code objects is deprecated, and may be removed in
Python 3.15.

* - .. attribute:: codeobject.co_stacksize
- The required stack size of the code object

Expand Down
2 changes: 1 addition & 1 deletion Doc/whatsnew/3.10.rst
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ Tracing events, with the correct line number, are generated for all lines of cod
The :attr:`~frame.f_lineno` attribute of frame objects will always contain the
expected line number.

The :attr:`~codeobject.co_lnotab` attribute of
The :attr:`!codeobject.co_lnotab` attribute of
:ref:`code objects <code-objects>` is deprecated and
will be removed in 3.12.
Code that needs to convert from offset to line number should use the new
Expand Down
2 changes: 1 addition & 1 deletion Doc/whatsnew/3.12.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1333,7 +1333,7 @@ Deprecated
``int``, convert to int explicitly: ``~int(x)``. (Contributed by Tim Hoffmann
in :gh:`103487`.)

* Accessing :attr:`~codeobject.co_lnotab` on code objects was deprecated in
* Accessing :attr:`!codeobject.co_lnotab` on code objects was deprecated in
Python 3.10 via :pep:`626`,
but it only got a proper :exc:`DeprecationWarning` in 3.12.
May be removed in 3.15.
Expand Down
8 changes: 8 additions & 0 deletions Doc/whatsnew/3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,14 @@ threading
(Contributed by Bénédikt Tran in :gh:`134087`.)


types
-----

* Removed deprecated in :pep:`626` since Python 3.12
:attr:`!codeobject.co_lnotab` from :class:`types.CodeType`.
(Contributed by Nikita Sobolev in :gh:`134690`.)


typing
------

Expand Down
2 changes: 1 addition & 1 deletion Doc/whatsnew/3.6.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2173,7 +2173,7 @@ Changes in the Python API
* :c:func:`PyErr_SetImportError` now sets :exc:`TypeError` when its **msg**
argument is not set. Previously only ``NULL`` was returned.

* The format of the :attr:`~codeobject.co_lnotab` attribute of code objects
* The format of the :attr:`!codeobject.co_lnotab` attribute of code objects
changed to support
a negative line number delta. By default, Python does not emit bytecode with
a negative line number delta. Functions using :attr:`frame.f_lineno`,
Expand Down
8 changes: 0 additions & 8 deletions InternalDocs/code_objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,6 @@ The `co_linetable` bytes object of code objects contains a compact
representation of the source code positions of instructions, which are
returned by the `co_positions()` iterator.

> [!NOTE]
> `co_linetable` is not to be confused with `co_lnotab`.
> For backwards compatibility, `co_lnotab` exposes the format
> as it existed in Python 3.10 and lower: this older format
> stores only the start line for each instruction.
> It is lazily created from `co_linetable` when accessed.
> See [`Objects/lnotab_notes.txt`](../Objects/lnotab_notes.txt) for more details.

`co_linetable` consists of a sequence of location entries.
Each entry starts with a byte with the most significant bit set, followed by
zero or more bytes with the most significant bit unset.
Expand Down
2 changes: 0 additions & 2 deletions Lib/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,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 @@ -1604,7 +1603,6 @@ 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
return frame.f_lineno

_FrameInfo = namedtuple('_FrameInfo', ('frame',) + Traceback._fields)
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 @@ -424,13 +424,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

@unittest.skipIf(_testinternalcapi is None, '_testinternalcapi is missing')
def test_returns_only_none(self):
value = True
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Removed deprecated in :pep:`626` since Python 3.12
:attr:`!codeobject.co_lnotab` from :class:`types.CodeType`.
84 changes: 0 additions & 84 deletions Objects/codeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1275,77 +1275,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 @@ -2617,18 +2546,6 @@ static PyMemberDef code_memberlist[] = {
};


static PyObject *
code_getlnotab(PyObject *self, void *closure)
{
PyCodeObject *code = _PyCodeObject_CAST(self);
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(PyObject *self, void *closure)
{
Expand Down Expand Up @@ -2666,7 +2583,6 @@ code_getcode(PyObject *self, void *closure)
}

static PyGetSetDef code_getsetlist[] = {
{"co_lnotab", code_getlnotab, NULL, NULL},
{"_co_code_adaptive", code_getcodeadaptive, NULL, NULL},
// The following old names are kept for backward compatibility.
{"co_varnames", code_getvarnames, NULL, NULL},
Expand Down
Loading
Loading