diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index e3d5a638131c90ef70213c0191c34f0175c2b784..42fe6ae2b8244345221086e62ce63b949b0e9507 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -1,22 +1,29 @@ name: Tests -on: [push, pull_request] + +on: + push: + branches: + - master + pull_request: + workflow_dispatch: + jobs: build: runs-on: ubuntu-20.04 strategy: matrix: - python-version: [3.6, 3.7, 3.8, 3.9, '3.10', 3.11-dev] + python-version: [3.6, 3.7, 3.8, 3.9, '3.10', 3.11, '3.12-dev'] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: run tests env: STACK_DATA_SLOW_TESTS: 1 run: | - pip install -U pip + pip install --upgrade pip pip install --upgrade coveralls setuptools setuptools_scm pep517 pip install .[tests] coverage run --source stack_data -m pytest diff --git a/setup.cfg b/setup.cfg index 05f3ddac28c780df1ae323fe2e072d76c409e77a..11cbe80eb01096ad35f660be42e5685b138a4af8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -16,6 +16,7 @@ classifiers = Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 + Programming Language :: Python :: 3.12 License :: OSI Approved :: MIT License Operating System :: OS Independent Topic :: Software Development :: Debuggers diff --git a/stack_data/utils.py b/stack_data/utils.py index 78ce2d60a400b0acb3753ca038412ed1b66d0199..ad8cd38dc46b41155cabf4ff264d6d4f4beef8ea 100644 --- a/stack_data/utils.py +++ b/stack_data/utils.py @@ -92,12 +92,13 @@ def is_frame(frame_or_tb: Union[FrameType, TracebackType]) -> bool: def iter_stack(frame_or_tb: Union[FrameType, TracebackType]) -> Iterator[Union[FrameType, TracebackType]]: - while frame_or_tb: - yield frame_or_tb - if is_frame(frame_or_tb): - frame_or_tb = frame_or_tb.f_back + current: Union[FrameType, TracebackType, None] = frame_or_tb + while current: + yield current + if is_frame(current): + current = current.f_back else: - frame_or_tb = frame_or_tb.tb_next + current = current.tb_next def frame_and_lineno(frame_or_tb: Union[FrameType, TracebackType]) -> Tuple[FrameType, int]: diff --git a/tests/__init__.py b/tests/__init__.py index fe281111c72be0728401c7f737866454cd6b88c1..e61d09f772b20e4fed930d68a2c0d93c55c2497e 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,7 +1,10 @@ import os import pyximport -from typeguard.importhook import install_import_hook +try: + from typeguard import install_import_hook +except ImportError: + from typeguard.importhook import install_import_hook pyximport.install(language_level=3) diff --git a/tests/golden_files/pygmented.txt b/tests/golden_files/pygmented.txt index 920dabc85f847d8c522c639533071beb9490dd36..c82f142cb629689da9f95b7a01cfa7d602adc583 100644 --- a/tests/golden_files/pygmented.txt +++ b/tests/golden_files/pygmented.txt @@ -1,11 +1,11 @@ Traceback (most recent call last): File "formatter_example.py", line 21, in foo - 9 | [38;5;15m[39m[38;5;15mx[39m[38;5;15m [39m[38;5;197m=[39m[38;5;15m [39m[38;5;141m1[39m - 10 | [38;5;15m[39m[38;5;15mlst[39m[38;5;15m [39m[38;5;197m=[39m[38;5;15m [39m[38;5;15m([39m + 9 | [38;5;15m[39m[38;5;15mx[39m[38;5;15m [39m[38;5;204m=[39m[38;5;15m [39m[38;5;141m1[39m + 10 | [38;5;15m[39m[38;5;15mlst[39m[38;5;15m [39m[38;5;204m=[39m[38;5;15m [39m[38;5;15m([39m 11 | [38;5;15m [39m[38;5;15m[[39m 12 | [38;5;15m [39m[38;5;15mx[39m[38;5;15m,[39m (...) - 18 | [38;5;15m [39m[38;5;197m+[39m[38;5;15m [39m[38;5;15m[[39m[38;5;15m][39m + 18 | [38;5;15m [39m[38;5;204m+[39m[38;5;15m [39m[38;5;15m[[39m[38;5;15m][39m 19 | [38;5;15m[39m[38;5;15m)[39m 20 | [38;5;15m[39m[38;5;81mtry[39m[38;5;15m:[39m --> 21 | [38;5;15m [39m[38;5;81mreturn[39m[38;5;15m [39m[38;5;15;48;5;24mint[39;49m[38;5;15;48;5;24m([39;49m[38;5;15;48;5;24mstr[39;49m[38;5;15;48;5;24m([39;49m[38;5;15;48;5;24mlst[39;49m[38;5;15;48;5;24m)[39;49m[38;5;15;48;5;24m)[39;49m @@ -19,7 +19,7 @@ Traceback (most recent call last): 21 | [38;5;15m [39m[38;5;81mreturn[39m[38;5;15m [39m[38;5;15mint[39m[38;5;15m([39m[38;5;15mstr[39m[38;5;15m([39m[38;5;15mlst[39m[38;5;15m)[39m[38;5;15m)[39m 22 | [38;5;15m[39m[38;5;81mexcept[39m[38;5;15m:[39m 23 | [38;5;15m [39m[38;5;81mtry[39m[38;5;15m:[39m ---> 24 | [38;5;15m [39m[38;5;81mreturn[39m[38;5;15m [39m[38;5;141;48;5;24m1[39;49m[38;5;15;48;5;24m [39;49m[38;5;197;48;5;24m/[39;49m[38;5;15;48;5;24m [39;49m[38;5;141;48;5;24m0[39;49m +--> 24 | [38;5;15m [39m[38;5;81mreturn[39m[38;5;15m [39m[38;5;141;48;5;24m1[39;49m[38;5;15;48;5;24m [39;49m[38;5;204;48;5;24m/[39;49m[38;5;15;48;5;24m [39;49m[38;5;141;48;5;24m0[39;49m 25 | [38;5;15m [39m[38;5;81mexcept[39m[38;5;15m [39m[38;5;148mException[39m[38;5;15m [39m[38;5;81mas[39m[38;5;15m [39m[38;5;15me[39m[38;5;15m:[39m ZeroDivisionError: division by zero @@ -31,24 +31,24 @@ Traceback (most recent call last): --> 30 | [38;5;15m [39m[38;5;15;48;5;24mexec[39;49m[38;5;15;48;5;24m([39;49m[38;5;186;48;5;24m"[39;49m[38;5;186;48;5;24mfoo()[39;49m[38;5;186;48;5;24m"[39;49m[38;5;15;48;5;24m)[39;49m File "<string>", line 1, in <module> File "formatter_example.py", line 8, in foo - 6 | [38;5;81mdef[39m[38;5;15m [39m[38;5;148mfoo[39m[38;5;15m([39m[38;5;15mn[39m[38;5;197m=[39m[38;5;141m5[39m[38;5;15m)[39m[38;5;15m:[39m - 7 | [38;5;15m [39m[38;5;81mif[39m[38;5;15m [39m[38;5;15mn[39m[38;5;15m [39m[38;5;197m>[39m[38;5;15m [39m[38;5;141m0[39m[38;5;15m:[39m ---> 8 | [38;5;15m [39m[38;5;81mreturn[39m[38;5;15m [39m[38;5;15;48;5;24mfoo[39;49m[38;5;15;48;5;24m([39;49m[38;5;15;48;5;24mn[39;49m[38;5;15;48;5;24m [39;49m[38;5;197;48;5;24m-[39;49m[38;5;15;48;5;24m [39;49m[38;5;141;48;5;24m1[39;49m[38;5;15;48;5;24m)[39;49m - 9 | [38;5;15m [39m[38;5;15mx[39m[38;5;15m [39m[38;5;197m=[39m[38;5;15m [39m[38;5;141m1[39m + 6 | [38;5;81mdef[39m[38;5;15m [39m[38;5;148mfoo[39m[38;5;15m([39m[38;5;15mn[39m[38;5;204m=[39m[38;5;141m5[39m[38;5;15m)[39m[38;5;15m:[39m + 7 | [38;5;15m [39m[38;5;81mif[39m[38;5;15m [39m[38;5;15mn[39m[38;5;15m [39m[38;5;204m>[39m[38;5;15m [39m[38;5;141m0[39m[38;5;15m:[39m +--> 8 | [38;5;15m [39m[38;5;81mreturn[39m[38;5;15m [39m[38;5;15;48;5;24mfoo[39;49m[38;5;15;48;5;24m([39;49m[38;5;15;48;5;24mn[39;49m[38;5;15;48;5;24m [39;49m[38;5;204;48;5;24m-[39;49m[38;5;15;48;5;24m [39;49m[38;5;141;48;5;24m1[39;49m[38;5;15;48;5;24m)[39;49m + 9 | [38;5;15m [39m[38;5;15mx[39m[38;5;15m [39m[38;5;204m=[39m[38;5;15m [39m[38;5;141m1[39m File "formatter_example.py", line 8, in foo - 6 | [38;5;81mdef[39m[38;5;15m [39m[38;5;148mfoo[39m[38;5;15m([39m[38;5;15mn[39m[38;5;197m=[39m[38;5;141m5[39m[38;5;15m)[39m[38;5;15m:[39m - 7 | [38;5;15m [39m[38;5;81mif[39m[38;5;15m [39m[38;5;15mn[39m[38;5;15m [39m[38;5;197m>[39m[38;5;15m [39m[38;5;141m0[39m[38;5;15m:[39m ---> 8 | [38;5;15m [39m[38;5;81mreturn[39m[38;5;15m [39m[38;5;15;48;5;24mfoo[39;49m[38;5;15;48;5;24m([39;49m[38;5;15;48;5;24mn[39;49m[38;5;15;48;5;24m [39;49m[38;5;197;48;5;24m-[39;49m[38;5;15;48;5;24m [39;49m[38;5;141;48;5;24m1[39;49m[38;5;15;48;5;24m)[39;49m - 9 | [38;5;15m [39m[38;5;15mx[39m[38;5;15m [39m[38;5;197m=[39m[38;5;15m [39m[38;5;141m1[39m + 6 | [38;5;81mdef[39m[38;5;15m [39m[38;5;148mfoo[39m[38;5;15m([39m[38;5;15mn[39m[38;5;204m=[39m[38;5;141m5[39m[38;5;15m)[39m[38;5;15m:[39m + 7 | [38;5;15m [39m[38;5;81mif[39m[38;5;15m [39m[38;5;15mn[39m[38;5;15m [39m[38;5;204m>[39m[38;5;15m [39m[38;5;141m0[39m[38;5;15m:[39m +--> 8 | [38;5;15m [39m[38;5;81mreturn[39m[38;5;15m [39m[38;5;15;48;5;24mfoo[39;49m[38;5;15;48;5;24m([39;49m[38;5;15;48;5;24mn[39;49m[38;5;15;48;5;24m [39;49m[38;5;204;48;5;24m-[39;49m[38;5;15;48;5;24m [39;49m[38;5;141;48;5;24m1[39;49m[38;5;15;48;5;24m)[39;49m + 9 | [38;5;15m [39m[38;5;15mx[39m[38;5;15m [39m[38;5;204m=[39m[38;5;15m [39m[38;5;141m1[39m [... skipping similar frames: foo at line 8 (2 times)] File "formatter_example.py", line 8, in foo - 6 | [38;5;81mdef[39m[38;5;15m [39m[38;5;148mfoo[39m[38;5;15m([39m[38;5;15mn[39m[38;5;197m=[39m[38;5;141m5[39m[38;5;15m)[39m[38;5;15m:[39m - 7 | [38;5;15m [39m[38;5;81mif[39m[38;5;15m [39m[38;5;15mn[39m[38;5;15m [39m[38;5;197m>[39m[38;5;15m [39m[38;5;141m0[39m[38;5;15m:[39m ---> 8 | [38;5;15m [39m[38;5;81mreturn[39m[38;5;15m [39m[38;5;15;48;5;24mfoo[39;49m[38;5;15;48;5;24m([39;49m[38;5;15;48;5;24mn[39;49m[38;5;15;48;5;24m [39;49m[38;5;197;48;5;24m-[39;49m[38;5;15;48;5;24m [39;49m[38;5;141;48;5;24m1[39;49m[38;5;15;48;5;24m)[39;49m - 9 | [38;5;15m [39m[38;5;15mx[39m[38;5;15m [39m[38;5;197m=[39m[38;5;15m [39m[38;5;141m1[39m + 6 | [38;5;81mdef[39m[38;5;15m [39m[38;5;148mfoo[39m[38;5;15m([39m[38;5;15mn[39m[38;5;204m=[39m[38;5;141m5[39m[38;5;15m)[39m[38;5;15m:[39m + 7 | [38;5;15m [39m[38;5;81mif[39m[38;5;15m [39m[38;5;15mn[39m[38;5;15m [39m[38;5;204m>[39m[38;5;15m [39m[38;5;141m0[39m[38;5;15m:[39m +--> 8 | [38;5;15m [39m[38;5;81mreturn[39m[38;5;15m [39m[38;5;15;48;5;24mfoo[39;49m[38;5;15;48;5;24m([39;49m[38;5;15;48;5;24mn[39;49m[38;5;15;48;5;24m [39;49m[38;5;204;48;5;24m-[39;49m[38;5;15;48;5;24m [39;49m[38;5;141;48;5;24m1[39;49m[38;5;15;48;5;24m)[39;49m + 9 | [38;5;15m [39m[38;5;15mx[39m[38;5;15m [39m[38;5;204m=[39m[38;5;15m [39m[38;5;141m1[39m File "formatter_example.py", line 26, in foo 23 | [38;5;15m[39m[38;5;81mtry[39m[38;5;15m:[39m - 24 | [38;5;15m [39m[38;5;81mreturn[39m[38;5;15m [39m[38;5;141m1[39m[38;5;15m [39m[38;5;197m/[39m[38;5;15m [39m[38;5;141m0[39m + 24 | [38;5;15m [39m[38;5;81mreturn[39m[38;5;15m [39m[38;5;141m1[39m[38;5;15m [39m[38;5;204m/[39m[38;5;15m [39m[38;5;141m0[39m 25 | [38;5;15m[39m[38;5;81mexcept[39m[38;5;15m [39m[38;5;148mException[39m[38;5;15m [39m[38;5;81mas[39m[38;5;15m [39m[38;5;15me[39m[38;5;15m:[39m ---> 26 | [38;5;15m [39m[38;5;81mraise[39m[38;5;15m [39m[38;5;148mTypeError[39m[38;5;15m [39m[38;5;197mfrom[39m[38;5;15m [39m[38;5;15me[39m +--> 26 | [38;5;15m [39m[38;5;81mraise[39m[38;5;15m [39m[38;5;148mTypeError[39m[38;5;15m [39m[38;5;204mfrom[39m[38;5;15m [39m[38;5;15me[39m TypeError diff --git a/tests/golden_files/serialize.json b/tests/golden_files/serialize.json index 94a190ac36548e64aba651ab2b3779cdf9464f70..f084d185a15ce07acfd67b008f655961bf471ebd 100644 --- a/tests/golden_files/serialize.json +++ b/tests/golden_files/serialize.json @@ -582,13 +582,13 @@ "type": "line", "is_current": false, "lineno": 9, - "text": "\u001b[38;5;15m\u001b[39m\u001b[38;5;15mx\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;197m=\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m1\u001b[39m" + "text": "\u001b[38;5;15m\u001b[39m\u001b[38;5;15mx\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;204m=\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m1\u001b[39m" }, { "type": "line", "is_current": false, "lineno": 10, - "text": "\u001b[38;5;15m\u001b[39m\u001b[38;5;15mlst\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;197m=\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15m(\u001b[39m" + "text": "\u001b[38;5;15m\u001b[39m\u001b[38;5;15mlst\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;204m=\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15m(\u001b[39m" }, { "type": "line", @@ -609,7 +609,7 @@ "type": "line", "is_current": false, "lineno": 18, - "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;197m+\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15m[\u001b[39m\u001b[38;5;15m]\u001b[39m" + "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;204m+\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15m[\u001b[39m\u001b[38;5;15m]\u001b[39m" }, { "type": "line", @@ -724,7 +724,7 @@ "type": "line", "is_current": true, "lineno": 24, - "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mreturn\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141;48;5;24m1\u001b[39;49m\u001b[38;5;15;48;5;24m \u001b[39;49m\u001b[38;5;197;48;5;24m/\u001b[39;49m\u001b[38;5;15;48;5;24m \u001b[39;49m\u001b[38;5;141;48;5;24m0\u001b[39;49m" + "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mreturn\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141;48;5;24m1\u001b[39;49m\u001b[38;5;15;48;5;24m \u001b[39;49m\u001b[38;5;204;48;5;24m/\u001b[39;49m\u001b[38;5;15;48;5;24m \u001b[39;49m\u001b[38;5;141;48;5;24m0\u001b[39;49m" }, { "type": "line", @@ -832,25 +832,25 @@ "type": "line", "is_current": false, "lineno": 6, - "text": "\u001b[38;5;81mdef\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;148mfoo\u001b[39m\u001b[38;5;15m(\u001b[39m\u001b[38;5;15mn\u001b[39m\u001b[38;5;197m=\u001b[39m\u001b[38;5;141m5\u001b[39m\u001b[38;5;15m)\u001b[39m\u001b[38;5;15m:\u001b[39m" + "text": "\u001b[38;5;81mdef\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;148mfoo\u001b[39m\u001b[38;5;15m(\u001b[39m\u001b[38;5;15mn\u001b[39m\u001b[38;5;204m=\u001b[39m\u001b[38;5;141m5\u001b[39m\u001b[38;5;15m)\u001b[39m\u001b[38;5;15m:\u001b[39m" }, { "type": "line", "is_current": false, "lineno": 7, - "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mif\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15mn\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;197m>\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m0\u001b[39m\u001b[38;5;15m:\u001b[39m" + "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mif\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15mn\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;204m>\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m0\u001b[39m\u001b[38;5;15m:\u001b[39m" }, { "type": "line", "is_current": true, "lineno": 8, - "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mreturn\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15;48;5;24mfoo\u001b[39;49m\u001b[38;5;15;48;5;24m(\u001b[39;49m\u001b[38;5;15;48;5;24mn\u001b[39;49m\u001b[38;5;15;48;5;24m \u001b[39;49m\u001b[38;5;197;48;5;24m-\u001b[39;49m\u001b[38;5;15;48;5;24m \u001b[39;49m\u001b[38;5;141;48;5;24m1\u001b[39;49m\u001b[38;5;15;48;5;24m)\u001b[39;49m" + "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mreturn\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15;48;5;24mfoo\u001b[39;49m\u001b[38;5;15;48;5;24m(\u001b[39;49m\u001b[38;5;15;48;5;24mn\u001b[39;49m\u001b[38;5;15;48;5;24m \u001b[39;49m\u001b[38;5;204;48;5;24m-\u001b[39;49m\u001b[38;5;15;48;5;24m \u001b[39;49m\u001b[38;5;141;48;5;24m1\u001b[39;49m\u001b[38;5;15;48;5;24m)\u001b[39;49m" }, { "type": "line", "is_current": false, "lineno": 9, - "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;15mx\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;197m=\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m1\u001b[39m" + "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;15mx\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;204m=\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m1\u001b[39m" } ], "variables": [ @@ -878,25 +878,25 @@ "type": "line", "is_current": false, "lineno": 6, - "text": "\u001b[38;5;81mdef\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;148mfoo\u001b[39m\u001b[38;5;15m(\u001b[39m\u001b[38;5;15mn\u001b[39m\u001b[38;5;197m=\u001b[39m\u001b[38;5;141m5\u001b[39m\u001b[38;5;15m)\u001b[39m\u001b[38;5;15m:\u001b[39m" + "text": "\u001b[38;5;81mdef\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;148mfoo\u001b[39m\u001b[38;5;15m(\u001b[39m\u001b[38;5;15mn\u001b[39m\u001b[38;5;204m=\u001b[39m\u001b[38;5;141m5\u001b[39m\u001b[38;5;15m)\u001b[39m\u001b[38;5;15m:\u001b[39m" }, { "type": "line", "is_current": false, "lineno": 7, - "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mif\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15mn\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;197m>\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m0\u001b[39m\u001b[38;5;15m:\u001b[39m" + "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mif\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15mn\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;204m>\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m0\u001b[39m\u001b[38;5;15m:\u001b[39m" }, { "type": "line", "is_current": true, "lineno": 8, - "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mreturn\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15;48;5;24mfoo\u001b[39;49m\u001b[38;5;15;48;5;24m(\u001b[39;49m\u001b[38;5;15;48;5;24mn\u001b[39;49m\u001b[38;5;15;48;5;24m \u001b[39;49m\u001b[38;5;197;48;5;24m-\u001b[39;49m\u001b[38;5;15;48;5;24m \u001b[39;49m\u001b[38;5;141;48;5;24m1\u001b[39;49m\u001b[38;5;15;48;5;24m)\u001b[39;49m" + "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mreturn\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15;48;5;24mfoo\u001b[39;49m\u001b[38;5;15;48;5;24m(\u001b[39;49m\u001b[38;5;15;48;5;24mn\u001b[39;49m\u001b[38;5;15;48;5;24m \u001b[39;49m\u001b[38;5;204;48;5;24m-\u001b[39;49m\u001b[38;5;15;48;5;24m \u001b[39;49m\u001b[38;5;141;48;5;24m1\u001b[39;49m\u001b[38;5;15;48;5;24m)\u001b[39;49m" }, { "type": "line", "is_current": false, "lineno": 9, - "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;15mx\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;197m=\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m1\u001b[39m" + "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;15mx\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;204m=\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m1\u001b[39m" } ], "variables": [ @@ -934,25 +934,25 @@ "type": "line", "is_current": false, "lineno": 6, - "text": "\u001b[38;5;81mdef\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;148mfoo\u001b[39m\u001b[38;5;15m(\u001b[39m\u001b[38;5;15mn\u001b[39m\u001b[38;5;197m=\u001b[39m\u001b[38;5;141m5\u001b[39m\u001b[38;5;15m)\u001b[39m\u001b[38;5;15m:\u001b[39m" + "text": "\u001b[38;5;81mdef\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;148mfoo\u001b[39m\u001b[38;5;15m(\u001b[39m\u001b[38;5;15mn\u001b[39m\u001b[38;5;204m=\u001b[39m\u001b[38;5;141m5\u001b[39m\u001b[38;5;15m)\u001b[39m\u001b[38;5;15m:\u001b[39m" }, { "type": "line", "is_current": false, "lineno": 7, - "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mif\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15mn\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;197m>\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m0\u001b[39m\u001b[38;5;15m:\u001b[39m" + "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mif\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15mn\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;204m>\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m0\u001b[39m\u001b[38;5;15m:\u001b[39m" }, { "type": "line", "is_current": true, "lineno": 8, - "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mreturn\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15;48;5;24mfoo\u001b[39;49m\u001b[38;5;15;48;5;24m(\u001b[39;49m\u001b[38;5;15;48;5;24mn\u001b[39;49m\u001b[38;5;15;48;5;24m \u001b[39;49m\u001b[38;5;197;48;5;24m-\u001b[39;49m\u001b[38;5;15;48;5;24m \u001b[39;49m\u001b[38;5;141;48;5;24m1\u001b[39;49m\u001b[38;5;15;48;5;24m)\u001b[39;49m" + "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mreturn\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15;48;5;24mfoo\u001b[39;49m\u001b[38;5;15;48;5;24m(\u001b[39;49m\u001b[38;5;15;48;5;24mn\u001b[39;49m\u001b[38;5;15;48;5;24m \u001b[39;49m\u001b[38;5;204;48;5;24m-\u001b[39;49m\u001b[38;5;15;48;5;24m \u001b[39;49m\u001b[38;5;141;48;5;24m1\u001b[39;49m\u001b[38;5;15;48;5;24m)\u001b[39;49m" }, { "type": "line", "is_current": false, "lineno": 9, - "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;15mx\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;197m=\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m1\u001b[39m" + "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;15mx\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;204m=\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m1\u001b[39m" } ], "variables": [ @@ -986,7 +986,7 @@ "type": "line", "is_current": false, "lineno": 24, - "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mreturn\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m1\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;197m/\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m0\u001b[39m" + "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mreturn\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m1\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;204m/\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;141m0\u001b[39m" }, { "type": "line", @@ -998,7 +998,7 @@ "type": "line", "is_current": true, "lineno": 26, - "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mraise\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;148mTypeError\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;197mfrom\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15me\u001b[39m" + "text": "\u001b[38;5;15m \u001b[39m\u001b[38;5;81mraise\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;148mTypeError\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;204mfrom\u001b[39m\u001b[38;5;15m \u001b[39m\u001b[38;5;15me\u001b[39m" } ], "variables": [ diff --git a/tests/test_core.py b/tests/test_core.py index 52ad3aeac1aa8f1a33cc4565d49e9b6b39984404..b0ecdc2f21a1b19d09f7cf31863d74f46667cc94 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -484,7 +484,7 @@ def sys_modules_sources(): for module in list(sys.modules.values()): try: filename = inspect.getsourcefile(module) - except TypeError: + except (TypeError, AttributeError): continue if not filename: @@ -630,7 +630,7 @@ x = 1 """ -@pytest.mark.skipif(pygments_version < (2, 12), reason="Different output in older Pygments") +@pytest.mark.skipif(pygments_version < (2, 14), reason="Different output in older Pygments") def test_pygments_example(): from .samples.pygments_example import bar result = bar() @@ -670,32 +670,32 @@ Terminal256Formatter <class \'stack_data.core.style_with_executing_node.<locals> TerminalFormatter native: - 13 | \x1b[34mdef\x1b[39;49;00m \x1b[32mbar\x1b[39;49;00m(): - 14 | x = \x1b[34m1\x1b[39;49;00m - 15 | \x1b[36mstr\x1b[39;49;00m(x) - 17 | \x1b[90m@deco\x1b[39;49;00m - 18 | \x1b[34mdef\x1b[39;49;00m \x1b[32mfoo\x1b[39;49;00m(): - 19 | \x1b[34mpass\x1b[39;49;00m + 13 | \x1b[34mdef\x1b[39;49;00m \x1b[32mbar\x1b[39;49;00m():\x1b[37m\x1b[39;49;00m + 14 | x = \x1b[34m1\x1b[39;49;00m\x1b[37m\x1b[39;49;00m + 15 | \x1b[36mstr\x1b[39;49;00m(x)\x1b[37m\x1b[39;49;00m + 17 | \x1b[90m@deco\x1b[39;49;00m\x1b[37m\x1b[39;49;00m + 18 | \x1b[34mdef\x1b[39;49;00m \x1b[32mfoo\x1b[39;49;00m():\x1b[37m\x1b[39;49;00m + 19 | \x1b[34mpass\x1b[39;49;00m\x1b[37m\x1b[39;49;00m ----- - 25 | \x1b[34mdef\x1b[39;49;00m \x1b[32mdeco\x1b[39;49;00m(f): - 26 | f.result = print_stack() - 27 | \x1b[34mreturn\x1b[39;49;00m f + 25 | \x1b[34mdef\x1b[39;49;00m \x1b[32mdeco\x1b[39;49;00m(f):\x1b[37m\x1b[39;49;00m + 26 | f.result = print_stack()\x1b[37m\x1b[39;49;00m + 27 | \x1b[34mreturn\x1b[39;49;00m f\x1b[37m\x1b[39;49;00m ----- ==================== TerminalFormatter <class \'stack_data.core.style_with_executing_node.<locals>.NewStyle\'>: - 13 | \x1b[34mdef\x1b[39;49;00m \x1b[32mbar\x1b[39;49;00m(): - 14 | x = \x1b[34m1\x1b[39;49;00m - 15 | \x1b[36mstr\x1b[39;49;00m(x) - 17 | \x1b[90m@deco\x1b[39;49;00m - 18 | \x1b[34mdef\x1b[39;49;00m \x1b[32mfoo\x1b[39;49;00m(): - 19 | \x1b[34mpass\x1b[39;49;00m + 13 | \x1b[34mdef\x1b[39;49;00m \x1b[32mbar\x1b[39;49;00m():\x1b[37m\x1b[39;49;00m + 14 | x = \x1b[34m1\x1b[39;49;00m\x1b[37m\x1b[39;49;00m + 15 | \x1b[36mstr\x1b[39;49;00m(x)\x1b[37m\x1b[39;49;00m + 17 | \x1b[90m@deco\x1b[39;49;00m\x1b[37m\x1b[39;49;00m + 18 | \x1b[34mdef\x1b[39;49;00m \x1b[32mfoo\x1b[39;49;00m():\x1b[37m\x1b[39;49;00m + 19 | \x1b[34mpass\x1b[39;49;00m\x1b[37m\x1b[39;49;00m ----- - 25 | \x1b[34mdef\x1b[39;49;00m \x1b[32mdeco\x1b[39;49;00m(f): - 26 | f.result = print_stack() - 27 | \x1b[34mreturn\x1b[39;49;00m f + 25 | \x1b[34mdef\x1b[39;49;00m \x1b[32mdeco\x1b[39;49;00m(f):\x1b[37m\x1b[39;49;00m + 26 | f.result = print_stack()\x1b[37m\x1b[39;49;00m + 27 | \x1b[34mreturn\x1b[39;49;00m f\x1b[37m\x1b[39;49;00m ----- ==================== @@ -753,9 +753,9 @@ HtmlFormatter <class \'stack_data.core.style_with_executing_node.<locals>.NewSty 13 | <span class="k">def</span> <span class="nf">bar</span><span class="p">():</span> 14 | <span class="n">x</span> <span class="o">=</span> <span class="mi">1</span> 15 | <span class="nb">str</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> - 17 | <span class=" -ExecutingNode"> </span><span class="nd nd-ExecutingNode">@deco</span><span class=" -ExecutingNode"></span> - 18 | <span class=" -ExecutingNode"> </span><span class="k k-ExecutingNode">def</span><span class=" -ExecutingNode"> </span><span class="nf nf-ExecutingNode">foo</span><span class="p p-ExecutingNode">():</span><span class=" -ExecutingNode"></span> - 19 | <span class=" -ExecutingNode"> </span><span class="k k-ExecutingNode">pass</span><span class=" -ExecutingNode"></span> + 17 | <span class=" -ExecutingNode"> </span><span class="nd nd-ExecutingNode">@deco</span> + 18 | <span class=" -ExecutingNode"> </span><span class="k k-ExecutingNode">def</span><span class=" -ExecutingNode"> </span><span class="nf nf-ExecutingNode">foo</span><span class="p p-ExecutingNode">():</span> + 19 | <span class=" -ExecutingNode"> </span><span class="k k-ExecutingNode">pass</span> ----- 25 | <span class="k">def</span> <span class="nf">deco</span><span class="p">(</span><span class="n">f</span><span class="p">):</span> 26 | <span class="n">f</span><span class="o">.</span><span class="n">result</span> <span class="o">=</span> <span class="n n-ExecutingNode">print_stack</span><span class="p p-ExecutingNode">()</span> diff --git a/tests/test_formatter.py b/tests/test_formatter.py index 31862f82e44ac409d3f06be641e897c462a34a5a..2ef9ecffff253f104a3f0f7c041f5e05187ea6e9 100644 --- a/tests/test_formatter.py +++ b/tests/test_formatter.py @@ -3,8 +3,9 @@ import re import sys from contextlib import contextmanager -import pytest import pygments +import pytest +from asttokens.util import fstring_positions_work from stack_data import Formatter, FrameInfo, Options, BlankLines from tests.utils import compare_to_file @@ -82,8 +83,7 @@ def test_example(capsys): if sys.version_info[:2] < (3, 8): f_string_suffix = 'old' - elif sys.version_info[:2] == (3, 8): - # lineno/col_offset in f-strings cannot be trusted in 3.8 + elif not fstring_positions_work(): f_string_suffix = '3.8' else: f_string_suffix = 'new' diff --git a/tests/test_serializer.py b/tests/test_serializer.py index 807872d508b31f02269022ca94a1e8023562d608..bc8acca3f79371e5f8f02e28f4b7a86cdb1cf766 100644 --- a/tests/test_serializer.py +++ b/tests/test_serializer.py @@ -39,4 +39,4 @@ def test_example(): ) - compare_to_file_json(result, "serialize") + compare_to_file_json(result, "serialize", pygmented=True) diff --git a/tests/utils.py b/tests/utils.py index 7ba00e2dfd16e5eb2d4b950c62088d6432906591..15000868c73f52bd648c217557309ab9b2ff45be 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,9 +1,19 @@ import os +import pygments from littleutils import string_to_file, file_to_string, json_to_file, file_to_json +def parse_version(version: str): + return tuple(int(x) for x in version.split(".")) + + +old_pygments = parse_version(pygments.__version__) < (2, 16, 1) + + def compare_to_file(text, name): + if old_pygments and "pygment" in name: + return filename = os.path.join( os.path.dirname(__file__), 'golden_files', @@ -16,7 +26,9 @@ def compare_to_file(text, name): assert text == expected_output -def compare_to_file_json(data, name): +def compare_to_file_json(data, name, *, pygmented): + if old_pygments and pygmented: + return filename = os.path.join( os.path.dirname(__file__), 'golden_files', diff --git a/tox.ini b/tox.ini index b613d58bdc4d4d81b796abf672d740df4c65c70d..e5c0a6661ccc46434b2e1b6447592cc65a494b17 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,9 @@ [tox] -envlist = py{36,37,38,39,310,311} +envlist = py{36,37,38,39,310,311,312} [testenv] commands = pytest {posargs} extras = tests passenv = STACK_DATA_SLOW_TESTS + FIX_STACK_DATA_TESTS