Skip to content

Commit

Permalink
Merge pull request #22 from alexmojaki/not-python
Browse files Browse the repository at this point in the history
Fallback to basic Source.pieces when there is no Source.tree. Fixes #21
  • Loading branch information
alexmojaki authored Feb 14, 2022
2 parents 3026317 + 457e53b commit 80ea278
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 10 deletions.
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ include_package_data = True
tests_require = pytest; typeguard; pygments; littleutils

[options.extras_require]
tests = pytest; typeguard; pygments; littleutils
tests = pytest; typeguard; pygments; littleutils; cython

[coverage:run]
relative_files = True
17 changes: 10 additions & 7 deletions stack_data/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,10 @@ def __init__(self, *args, **kwargs):
@cached_property
def pieces(self) -> List[range]:
if not self.tree:
raise AttributeError("This file doesn't contain valid Python, so .pieces doesn't exist")
return [
range(i, i + 1)
for i in range(1, len(self.lines) + 1)
]
return list(self._clean_pieces())

@cached_property
Expand Down Expand Up @@ -352,7 +355,7 @@ def render(
If strip_leading_indent is true (the default) then leading spaces
common to all lines in this frame will be excluded.
"""
if pygmented:
if pygmented and self.frame_info.scope:
assert_(not markers, ValueError("Cannot use pygmented with markers"))
start_line, lines = self.frame_info._pygmented_scope_lines
result = lines[self.lineno - start_line]
Expand Down Expand Up @@ -569,10 +572,12 @@ def _frame_key(x):
@cached_property
def scope_pieces(self) -> List[range]:
"""
All the pieces (ranges of lines) contained in this object's .scope.
All the pieces (ranges of lines) contained in this object's .scope,
unless there is no .scope (because the source isn't valid Python syntax)
in which case it returns all the pieces in the source file, each containing one line.
"""
if not self.scope:
return []
return self.source.pieces

scope_start, scope_end = line_range(self.scope)
return [
Expand Down Expand Up @@ -619,9 +624,6 @@ def executing_piece(self) -> range:
"""
The piece (range of lines) containing the line currently being executed
by the interpreter in this frame.
Raises an exception if .scope is None, which usually means the source code
for this frame is unavailable.
"""
return only(
piece
Expand Down Expand Up @@ -701,6 +703,7 @@ def lines(self) -> List[Union[Line, LineGap]]:
for i, piece in enumerate(pieces):
if (
i == 1
and self.scope
and pieces[0] == self.scope_pieces[0]
and pieces[1] != self.scope_pieces[1]
):
Expand Down
4 changes: 4 additions & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import os

import pyximport
from typeguard.importhook import install_import_hook

pyximport.install()

if not os.environ.get("STACK_DATA_SLOW_TESTS"):
install_import_hook(["stack_data"])
11 changes: 11 additions & 0 deletions tests/golden_files/cython_example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Traceback (most recent call last):
File "cython_example.pyx", line 2, in tests.samples.cython_example.foo
1 | def foo():
--> 2 | bar()
3 |
File "cython_example.pyx", line 5, in tests.samples.cython_example.bar
2 | bar()
3 |
4 | cdef bar():
--> 5 | raise ValueError("bar!")
ValueError: bar!
5 changes: 5 additions & 0 deletions tests/samples/cython_example.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
def foo():
bar()

cdef bar():
raise ValueError("bar!")
1 change: 0 additions & 1 deletion tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,6 @@ def test_invalid_source():
filename = str(samples_dir / "not_code.txt")
source = Source.for_filename(filename)
assert not source.tree
assert not hasattr(source, "pieces")
assert not hasattr(source, "tokens_by_lineno")


Expand Down
10 changes: 9 additions & 1 deletion tests/test_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def format_variable_value(self, value) -> str:

class MyFormatter(BaseFormatter):
def format_frame(self, frame):
if not frame.filename.endswith(("formatter_example.py", "<string>")):
if not frame.filename.endswith(("formatter_example.py", "<string>", "cython_example.pyx")):
return
yield from super().format_frame(frame)

Expand Down Expand Up @@ -72,3 +72,11 @@ def check_example(name):
f_string()
except Exception:
MyFormatter().print_exception()

from .samples import cython_example

with check_example("cython_example"):
try:
cython_example.foo()
except Exception:
MyFormatter().print_exception()

0 comments on commit 80ea278

Please sign in to comment.