alexmojaki / stack_data

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bug: no lines available when using Python 3.10.0b3 (latest beta version)

aroberge opened this issue · comments

When running Python 3.10.0b3 on Windows, I found a case where no lines are captured by stack_data when an exception is raised.

Here's the content of a test file that demonstrate this:

import sys
import platform

from stack_data import FrameInfo

print(platform.python_version_tuple())

def print_stack():
    for frame_info in FrameInfo.stack_data(sys.exc_info()[2]):
        if isinstance(frame_info, FrameInfo):
            print(f"{frame_info.code.co_name} at line {frame_info.lineno}")
            print("-----------")
            for line in frame_info.lines:
                print(f"{'-->' if line.is_current else '   '} {line.lineno:4} | {line.render()}")
        else:
            print(f"... {frame_info.description} ...\n")

a, b = "a", "b"

try:
    c = [a   #
         .b]
except:
    print_stack()

Using Python 3.9.5, here's the output:

('3', '9', '5')
<module> at line 21
-----------
      16 |             print(f"... {frame_info.description} ...\n")
      18 | a, b = "a", "b"
      20 | try:
-->   21 |     c = [a   #
      22 |          .b]
      23 | except:

Using Python 3.10.0b3, no line are rendered:

('3', '10', '0b3')
<module> at line 22
-----------

Thanks for the report. This is an interesting case. The AST node of the attribute has lineno where the node starts with a but in 3.10 the exception is raised on the next line with .b to indicate the attribute access happening there. There's actually no AST node whose lineno is at the line where the exception is raised. So when executing is asked for statements found at that line, it returns nothing.

This is the first time I've seen this kind of mismatch, and I think my own report is what led to it: https://bugs.python.org/issue39316

This will need to be fixed in executing. Fortunately new Python versions have end_lineno which should help since I can't rely on lineno any more.

Thanks. If you fix it on executing, please let me know. Right now, after making changes to use stack_data, I had to resort to an hack to be able to extract the source (I will upload this soon), but the rest of the analysis fails, unsurprisingly.

I thought that end_lineno was only for SyntaxErrors ...

end_lineno was recently added to AST nodes, I think in 3.8. This is independent from exceptions.

I don't know if I wasn't clear or if this is a difference of opinion, but it's not a bug, it's a feature. The line is showing what the frame was doing at the time that led to the error: accessing the attribute .b or .two.

The difference becomes even more important when calling a method with no arguments. Compare the two versions when running this:

class A:
    def b(self):
        1 / 0


x = (
    A()
        .b()
)

Where this has really gotten to me is when I run the pycharm debugger and put a breakpoint on the .b() line because that's what I want to step into and it never gets hit because according to Python no operations happen on that line. Having that fixed in 3.10 is great.

I see what you mean. May I suggest that you comment on the issue I filed in the Python bug tracker?

Sure, I just wanted to make sure that we were on the same page before contradicting you on another forum, wasn't sure how that'd be taken.

This should now be fixed in the new executing version.