Thanks to visit codestin.com
Credit goes to github.com

Skip to content

gh-101865: Deprecate co_lnotab from code objects as per PEP 626 #101866

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

Merged
merged 10 commits into from
Apr 3, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Revert "gh-101865: Remove deprecated co_lnotab from code objects as…
… per PEP626"

This reverts commit 06a79d9.
  • Loading branch information
sobolevn committed Feb 21, 2023
commit dd65849ac6570f40b51fc11632841d51689d8eb1
4 changes: 4 additions & 0 deletions Doc/library/inspect.rst
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ 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
5 changes: 4 additions & 1 deletion Doc/reference/datamodel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,7 @@ Internal types
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 All @@ -988,7 +989,9 @@ Internal types
a tuple containing the literals used by the bytecode; :attr:`co_names` is
a tuple containing the names used by the bytecode; :attr:`co_filename` is
the filename from which the code was compiled; :attr:`co_firstlineno` is
the first line number of the function; :attr:`co_stacksize` is the
the first line number of the function; :attr:`co_lnotab` is a string
encoding the mapping from bytecode offsets to line numbers (for details
see the source code of the interpreter); :attr:`co_stacksize` is the
required stack size; :attr:`co_flags` is an integer encoding a number
of flags for the interpreter.

Expand Down
4 changes: 0 additions & 4 deletions Doc/whatsnew/3.12.rst
Original file line number Diff line number Diff line change
Expand Up @@ -700,10 +700,6 @@ Removed
*context* parameter instead.
(Contributed by Victor Stinner in :gh:`94172`.)

* Remove ``co_lnotab`` attribute from code objects per :pep:`626`:
use ``co_lines`` method instead.
(Contributed by Nikita Sobolev in :gh:`101865`.)


Porting to Python 3.12
======================
Expand Down
2 changes: 2 additions & 0 deletions Lib/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ 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 @@ -1707,6 +1708,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
return frame.f_lineno

_FrameInfo = namedtuple('_FrameInfo', ('frame',) + Traceback._fields)
Expand Down
13 changes: 8 additions & 5 deletions Lib/pydoc_data/topics.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Autogenerated by Sphinx on Mon Feb 13 10:21:05 2023
# Autogenerated by Sphinx on Tue Feb 7 13:18:04 2023
topics = {'assert': 'The "assert" statement\n'
'**********************\n'
'\n'
Expand Down Expand Up @@ -13704,10 +13704,13 @@
' bytecode; "co_filename" is the filename from which the code '
'was\n'
' compiled; "co_firstlineno" is the first line number of the\n'
' function; "co_stacksize" is the required stack size; '
'"co_flags"\n'
' is an integer encoding a number of flags for the '
'interpreter.\n'
' function; "co_lnotab" is a string encoding the mapping from\n'
' bytecode offsets to line numbers (for details see the source\n'
' code of the interpreter); "co_stacksize" is the required '
'stack\n'
' size; "co_flags" is an integer encoding a number of flags '
'for\n'
' the interpreter.\n'
'\n'
' The following flag bits are defined for "co_flags": bit '
'"0x04"\n'
Expand Down

This file was deleted.

20 changes: 19 additions & 1 deletion Misc/gdbinit
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,25 @@ end
# A rewrite of the Python interpreter's line number calculator in GDB's
# command language
define lineno
printf "%d", f->f_lineno
set $__continue = 1
set $__co = f->f_code
set $__lasti = f->f_lasti
set $__sz = ((PyVarObject *)$__co->co_lnotab)->ob_size/2
set $__p = (unsigned char *)((PyBytesObject *)$__co->co_lnotab)->ob_sval
set $__li = $__co->co_firstlineno
set $__ad = 0
while ($__sz-1 >= 0 && $__continue)
set $__sz = $__sz - 1
set $__ad = $__ad + *$__p
set $__p = $__p + 1
if ($__ad > $__lasti)
set $__continue = 0
else
set $__li = $__li + *$__p
set $__p = $__p + 1
end
end
printf "%d", $__li
end

define pyframev
Expand Down
78 changes: 78 additions & 0 deletions Objects/codeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,77 @@ _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 @@ -1810,6 +1881,12 @@ static PyMemberDef code_memberlist[] = {
};


static PyObject *
code_getlnotab(PyCodeObject *code, void *closure)
{
return decode_linetable(code);
}

static PyObject *
code_getvarnames(PyCodeObject *code, void *closure)
{
Expand Down Expand Up @@ -1842,6 +1919,7 @@ 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
Loading