mis*_*awa 1 c python python-3.x python-internals
testing on ../../test/test_patm.py
python: Python/compile.c:4420: int assemble_lnotab(struct assembler *,
struct instr *): Assertion `d_lineno >= 0' failed.
Aborted
Run Code Online (Sandbox Code Playgroud)
运行我的测试程序时,我收到了上面给出的错误.最后我发现Python3.5和Python3.6的源代码差别很小.只需一行:
Python3.5
static int
assemble_lnotab(struct assembler *a, struct instr *i)
{
int d_bytecode, d_lineno;
Py_ssize_t len;
unsigned char *lnotab;
d_bytecode = a->a_offset - a->a_lineno_off;
d_lineno = i->i_lineno - a->a_lineno;
assert(d_bytecode >= 0);
assert(d_lineno >= 0); // the only difference
if(d_bytecode == 0 && d_lineno == 0)
return 1;
...
Run Code Online (Sandbox Code Playgroud)
Python 3.6
static int
assemble_lnotab(struct assembler *a, struct instr *i)
{
int d_bytecode, d_lineno;
Py_ssize_t len;
unsigned char *lnotab;
d_bytecode = (a->a_offset - a->a_lineno_off) * sizeof(_Py_CODEUNIT);
d_lineno = i->i_lineno - a->a_lineno;
assert(d_bytecode >= 0);
if(d_bytecode == 0 && d_lineno == 0)
return 1;
Run Code Online (Sandbox Code Playgroud)
如果我刚删除assert(d_lineno >= 0);怎么办?
您正在使用3.5 的调试版本.在Python 3.5和任何以前的版本中,单个字节码块中的行编号(即模块的字节码或函数)必须是单调的,即每个操作码必须映射到源代码中的行,其中亚麻码必须是大于或等于前一个操作码的行号.在调试版本中检查过这个问题; 在Python的发布版本中,assert不会编译,但生成的行号选项卡无论如何都是无效的.
有关bugs.python.org的问题26107 对此进行了讨论.对行数单调性的要求被认为对优化有害,其中许多将重新组织生成的字节码.因此,在3.6中删除了检查以及使行号delta为有符号整数的其他更改.
您可以非常安全地注释掉这个断言,因为版本构建无论如何都会消除它,但是不要期望调试在生成的代码中正常工作,因为行号选项卡现在无效.
作为替代方案,如果您重新组织AST中的行或类似的行,您可以将所有行号设置为0 - 而不仅仅是丢失的行号; 或者你可以生成不违反单调性规则的假行号.
生成的AST出现了巧合问题,因为它 ast.fix_missing_locations会将行号0写入缺少行号的任何节点.如果AST的某些部分包含因为它们来源的行号ast.parse,那么生成的AST树很可能会破坏单调性要求 - 这也只会导致Pythons <3.6的非释放构建出现问题.
与此处的错误无关的另一个变化是从字节码到字代码的变化,这也是在Python 3.6中引入的.这里每个操作码都是一个16位字,而不是一个8位字节,可能有扩展的args.这就是偏移量乘以的原因sizeof(_Py_CODEUNIT);.
| 归档时间: |
|
| 查看次数: |
96 次 |
| 最近记录: |