diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 18b923cfe..c46f002ae 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -10,10 +10,8 @@ jobs: matrix: os: [windows-latest, ubuntu-latest, macos-latest] python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] - include: - - { os: ubuntu-latest, python-version: "3.7" } - - { os: windows-latest, python-version: "3.7" } - - { os: macos-12, python-version: "3.7" } + exclude: + - { os: windows-latest, python-version: "3.13" } defaults: run: shell: bash diff --git a/CHANGELOG.md b/CHANGELOG.md index ced2cc25a..59e8a1879 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- Rich will display tracebacks with finely grained error locations on python 3.11+ https://github.com/Textualize/rich/pull/3486 + ## [13.8.1] - 2024-09-10 ### Fixed diff --git a/poetry.lock b/poetry.lock index 2fae20b2a..637d25d6a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "appnope" @@ -13,106 +13,20 @@ files = [ [[package]] name = "asv" -version = "0.6.4" +version = "0.5.1" description = "Airspeed Velocity: A simple Python history benchmarking tool" optional = false -python-versions = ">=3.7" -files = [ - {file = "asv-0.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e32b4cc435bdb6f2ef83d8092e977962f6fa20471542d6341e596324d350cbea"}, - {file = "asv-0.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fdfb9090623fc45cbeb77ab40b394779794083c155128e3d320fa06af2e0fdf5"}, - {file = "asv-0.6.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5dfee8a415f4b5da0be4bedf4c9cb3b041c2148d28d2327cf3b54f9cb565cefd"}, - {file = "asv-0.6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abc13331bb8bb1880dbc33e75175ae90bca439038a1f7e246528481ecebd15dd"}, - {file = "asv-0.6.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b67eec004f8218bba25dcdbdda2e6676dd6c4ac3e97a80b691b27dcfbfbda38d"}, - {file = "asv-0.6.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:aef14496a34552308d054db71181bfb1ca45d7ef29028747d388be9f00a5b45c"}, - {file = "asv-0.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:0c8931e7a8aeda75f90b3ac422cbb7c46a5ce50d8c0a8e821cdf3e4d0705dd76"}, - {file = "asv-0.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:74666c5896b4aec92b4a12cf9aa7494dec3398bb9ea602a9f8dc1656b53e8e10"}, - {file = "asv-0.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26166a7bd7fe05b5a8507247d1a7ab1dfc4256414b0505d124a7b9d46a618a1c"}, - {file = "asv-0.6.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe6161c5616f5aed936947866b6376e09c937d628aa81115b3c72e90a151c1f9"}, - {file = "asv-0.6.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4d6122b5e86bf9071b9ff7136672d50da0d460dfc958f43429843f7a3cd3e86a"}, - {file = "asv-0.6.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:79554f125033ecbcb599cd704b4b5b525d254e5e05b1dd24bab3bbd83ae5502e"}, - {file = "asv-0.6.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2e80f39501628fd4cac972f08fa4c9b8e211a86fc43dd6e58c95d106cbaf54e7"}, - {file = "asv-0.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:363dfdee98cc072e6a1468137eed640985e48ccbb11c175d04ee420f05459872"}, - {file = "asv-0.6.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:244b71778f91aa6672e1f16feb9eecac78ef7cee95228ef8f0315a2e2deecfed"}, - {file = "asv-0.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3e798b275de2889748d43d42305bfce68c015a3e38ae935d231835cb836fef73"}, - {file = "asv-0.6.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d064c5ac1ab18efc62467f65ed4989a2e2ac1a4d21886119fa0ef0f91d548438"}, - {file = "asv-0.6.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c51e5862bdac0f1fe11886bdd40b30a9691a65cb7feac40f0676fe9206d5bb43"}, - {file = "asv-0.6.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46a7ca838e8c49109c43b1cda0eb64abc5e0a045538da718abe981d115ed47aa"}, - {file = "asv-0.6.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f5f722178c7e36b797f764c837fc03c462f68c8f2cba5145b2e64119e46231ff"}, - {file = "asv-0.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:f972ca71316d46a0242eb69e53dadfeab1e4d0546773b0f722462f97b3e5fbd9"}, - {file = "asv-0.6.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e8c728707d417268560d1e1a5cb0b638c10b346648b3338ca4dce373c0a0608b"}, - {file = "asv-0.6.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cfe2796c87960c90809a891e0805df7017fea58b86a739fbc901de9703f7685"}, - {file = "asv-0.6.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb74b1726280422c22e69010ede8bbd13309408b046d93af2ef199728d5f341a"}, - {file = "asv-0.6.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2223db773e31ffb4583f44ab8adbe3676e41db8d08e9ca59a9b95c7c26954133"}, - {file = "asv-0.6.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d7426c1d7c18c7f19689b0f060e77d7dce8ff32697e194aca236a8c100bf8b78"}, - {file = "asv-0.6.4-cp37-cp37m-win_amd64.whl", hash = "sha256:7d792a650e2f6bcab7c0f4278b305ee8cc9a16479dc7297bafbd5197a553d812"}, - {file = "asv-0.6.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7e396f602966c92e21e34c2a46f2be5161b0c4c1e3e87397e04a848e62a3c90b"}, - {file = "asv-0.6.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:14788182ab143e7c7af755b83c34887873a0bde6faa3b263a9f732247a4ae84f"}, - {file = "asv-0.6.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59ff949fae7c4b006aa94f46c9a9c02d9b79b1b836a6e3fcc5da633a2ab60aa2"}, - {file = "asv-0.6.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27fcce30845de881a58ee98eb9b51e3deb520356ee8423bf471585e62c7c2a60"}, - {file = "asv-0.6.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea066af743856d983fbd1973788032ef98cc28dc8e821ee065d25a3af4b791a0"}, - {file = "asv-0.6.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa248b4ad640310fd6d1a8265ee2672d6dbf019b32569a37a01aece49fe72d1b"}, - {file = "asv-0.6.4-cp38-cp38-win_amd64.whl", hash = "sha256:9419c426b441df380ff35f08a5323b73def19e17a13bee7a12ef0cbabbe8640b"}, - {file = "asv-0.6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:755f2ec48b8277f68be6ba6325c16d76665a9807245ac4f40bb223cf266701bf"}, - {file = "asv-0.6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8091787fd5219dc63e1c8dc2786da5f9ad5302b15b22c70cf14ee76bc20b3443"}, - {file = "asv-0.6.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cff89881dc7036f3fb4e50fb23dfef6768ae9651daf2efff18bd487339ab1f14"}, - {file = "asv-0.6.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b22bbe5a8bcea54b9d71bd02e78a814b1bfe7edeec171b1ecdeea839b78735a2"}, - {file = "asv-0.6.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:76b7ee6d6c63825065b5b250271d0576d39cc610674a128f5a39cc040b6a7d86"}, - {file = "asv-0.6.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:758d9982f6be463711dca19dda59bc51a2fee27ab2494132f453d92f3c121d43"}, - {file = "asv-0.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:9a16c3b8d533cc6a05a9a217a03c631b738047fca711c95aa3f07e4a83723198"}, - {file = "asv-0.6.4-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0305e9eee21f71c3d3f8b046beb35e571f6dd7ed2fcd0e8405f8a208bcd3228a"}, - {file = "asv-0.6.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6cd23fa20edf8cb30354fda3388a8835a15158e21559c86f0d997e5d30dbf91"}, - {file = "asv-0.6.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7424d2dbfcb98aa3c099311100ceb9aabfd83fed0b41420f70f142852ed392a"}, - {file = "asv-0.6.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7f4b95583cf379015d35b747a1bb4df99c05dd4107d6081b2cf4a577f4caeca"}, - {file = "asv-0.6.4-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e54b3e7c6a22af2ac779bf2767dcb6ee09760d9c4272b73e4d63a5ed938145d8"}, - {file = "asv-0.6.4-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f34b1568d353d6cddcfa074eba0aaaa82b29540df10614cf66f43930ba7827c1"}, - {file = "asv-0.6.4-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ccfbbc4f12e145ffb7a653275d75d54f72768f1ff1fdb300e0603dbf33deaf6"}, - {file = "asv-0.6.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:64637299bcbd7743da0140d8a19a732c33d9e41d28aa4db0bf1e58e12eb8b4e4"}, - {file = "asv-0.6.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bad0f37940c5ad7c39d81eecfc3c515f55c51bbca094e0efda4d70c74363532b"}, - {file = "asv-0.6.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfc9f90a7dd45f042f947f4c3a3d98ee591f5ac7d1751b541632e5f14fc35c54"}, - {file = "asv-0.6.4-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:356fbc8abf3f4c2b13bc37af78f08c008f1ef4320549e44c02a5a3f6a783f892"}, - {file = "asv-0.6.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:647a6ba8f6e9a23455aabc7a6365aa1feeeb82a6bf99696e0bc964aebe337730"}, - {file = "asv-0.6.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:80c791206e7c01b5883e8facd7ef27432a01fd1cbc4977d38f7bfe08ee98150a"}, - {file = "asv-0.6.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc49bb48295a4b1d902590b87e7920ee51e95d72bcf1c44d83303dfbecc68e2"}, - {file = "asv-0.6.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:022723563d770b43c50615e4b18d1ad861c00fcd91343bfbd51d21bfff708d4c"}, - {file = "asv-0.6.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:71d2ba7b16c462b92cd36c2a4d07753bb6c995149a830ce1d4246f6061bf3f1d"}, - {file = "asv-0.6.4.tar.gz", hash = "sha256:1d124184171cfe106e3e57ac04e3221b8d4571c9bd6ca2c6498a8c7407339df1"}, -] - -[package.dependencies] -asv-runner = ">=v0.2.1" -build = "*" -colorama = {version = "*", markers = "platform_system == \"Windows\""} -json5 = "*" -pympler = {version = "*", markers = "platform_python_implementation != \"PyPy\""} -pyyaml = {version = "*", markers = "platform_python_implementation != \"PyPy\""} -tabulate = "*" -tomli = {version = "*", markers = "python_version < \"3.11\""} -virtualenv = "*" - -[package.extras] -dev = ["isort (>=5.11.5)", "ruff"] -doc = ["sphinx", "sphinx-bootstrap-theme"] -hg = ["python-hglib"] -plugs = ["asv-bench-memray"] -test = ["feedparser", "filelock", "flaky", "numpy", "pytest", "pytest-rerunfailures", "pytest-rerunfailures (>=10.0)", "pytest-timeout", "pytest-xdist", "python-hglib", "rpy2", "scipy", "selenium", "virtualenv"] -virtualenv = ["packaging", "virtualenv"] - -[[package]] -name = "asv-runner" -version = "0.2.1" -description = "Core Python benchmark code for ASV" -optional = false -python-versions = ">=3.7" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ - {file = "asv_runner-0.2.1-py3-none-any.whl", hash = "sha256:655d466208ce311768071f5003a61611481b24b3ad5ac41fb8a6374197e647e9"}, - {file = "asv_runner-0.2.1.tar.gz", hash = "sha256:945dd301a06fa9102f221b1e9ddd048f5ecd863796d4c8cd487f5577fe0db66d"}, + {file = "asv-0.5.1.tar.gz", hash = "sha256:805fc3cc46c0bcf3e7baeaa16a12e4b92f1276c25490db4cb80fc541afa52bfc"}, ] [package.dependencies] -importlib-metadata = "*" +six = ">=1.4" [package.extras] -docs = ["furo", "myst-parser (>=2)", "sphinx", "sphinx-autobuild", "sphinx-autodoc2 (>=0.4.2)", "sphinx-contributors", "sphinx-copybutton", "sphinx-design", "sphinxcontrib-spelling"] +hg = ["python-hglib (>=1.5)"] +testing = ["feedparser", "filelock", "numpy", "pip", "pytest (>=4.4.0)", "pytest (>=4.4.0,<5.0)", "pytest-faulthandler", "pytest-faulthandler (<2.0)", "pytest-rerunfailures (>=8.0)", "pytest-rerunfailures (>=8.0,<9.0)", "pytest-timeout", "pytest-xdist", "python-hglib", "scipy", "selenium", "setuptools", "six", "virtualenv (>=1.7)", "wheel"] [[package]] name = "attrs" @@ -178,30 +92,6 @@ d = ["aiohttp (>=3.7.4)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] -[[package]] -name = "build" -version = "1.1.1" -description = "A simple, correct Python build frontend" -optional = false -python-versions = ">= 3.7" -files = [ - {file = "build-1.1.1-py3-none-any.whl", hash = "sha256:8ed0851ee76e6e38adce47e4bee3b51c771d86c64cf578d0c2245567ee200e73"}, - {file = "build-1.1.1.tar.gz", hash = "sha256:8eea65bb45b1aac2e734ba2cc8dad3a6d97d97901a395bd0ed3e7b46953d2a31"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "os_name == \"nt\""} -importlib-metadata = {version = ">=4.6", markers = "python_full_version < \"3.10.2\""} -packaging = ">=19.0" -pyproject_hooks = "*" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} - -[package.extras] -docs = ["furo (>=2023.08.17)", "sphinx (>=7.0,<8.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)", "sphinx-issues (>=3.0.0)"] -test = ["filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "setuptools (>=56.0.0)", "setuptools (>=67.8.0)", "wheel (>=0.36.0)"] -typing = ["importlib-metadata (>=5.1)", "mypy (>=1.5.0,<1.6.0)", "tomli", "typing-extensions (>=3.7.4.3)"] -virtualenv = ["virtualenv (>=20.0.35)"] - [[package]] name = "cfgv" version = "3.3.1" @@ -505,20 +395,6 @@ docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alab qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] -[[package]] -name = "json5" -version = "0.9.16" -description = "A Python implementation of the JSON5 data format." -optional = false -python-versions = "*" -files = [ - {file = "json5-0.9.16-py2.py3-none-any.whl", hash = "sha256:da983e23cfd797444c690600e9bd6675608f25355b06aef672ffb927f888c07d"}, - {file = "json5-0.9.16.tar.gz", hash = "sha256:9069400db2f44c78a22a4e838cca7b5a7dc5546877a972497e78c5b783ebaffa"}, -] - -[package.extras] -dev = ["hypothesis"] - [[package]] name = "jupyterlab-widgets" version = "3.0.13" @@ -802,31 +678,6 @@ files = [ plugins = ["importlib-metadata"] windows-terminal = ["colorama (>=0.4.6)"] -[[package]] -name = "pympler" -version = "1.1" -description = "A development tool to measure, monitor and analyze the memory behavior of Python objects." -optional = false -python-versions = ">=3.6" -files = [ - {file = "Pympler-1.1-py3-none-any.whl", hash = "sha256:5b223d6027d0619584116a0cbc28e8d2e378f7a79c1e5e024f9ff3b673c58506"}, - {file = "pympler-1.1.tar.gz", hash = "sha256:1eaa867cb8992c218430f1708fdaccda53df064144d1c5656b1e6f1ee6000424"}, -] - -[package.dependencies] -pywin32 = {version = ">=226", markers = "platform_system == \"Windows\""} - -[[package]] -name = "pyproject-hooks" -version = "1.1.0" -description = "Wrappers to call pyproject.toml-based build backend hooks." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pyproject_hooks-1.1.0-py3-none-any.whl", hash = "sha256:7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2"}, - {file = "pyproject_hooks-1.1.0.tar.gz", hash = "sha256:4b37730834edbd6bd37f26ece6b44802fb1c1ee2ece0e54ddff8bfc06db86965"}, -] - [[package]] name = "pytest" version = "7.4.4" @@ -868,29 +719,6 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] -[[package]] -name = "pywin32" -version = "306" -description = "Python for Window Extensions" -optional = false -python-versions = "*" -files = [ - {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, - {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, - {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, - {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, - {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, - {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, - {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, - {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, - {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, - {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, - {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, - {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, - {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, - {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, -] - [[package]] name = "pyyaml" version = "6.0.1" @@ -957,19 +785,16 @@ testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[l testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] -name = "tabulate" -version = "0.9.0" -description = "Pretty-print tabular data" +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=3.7" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ - {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, - {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] -[package.extras] -widechars = ["wcwidth"] - [[package]] name = "tomli" version = "2.0.1" @@ -1059,13 +884,13 @@ files = [ [[package]] name = "virtualenv" -version = "20.26.3" +version = "20.26.4" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.26.3-py3-none-any.whl", hash = "sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589"}, - {file = "virtualenv-20.26.3.tar.gz", hash = "sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a"}, + {file = "virtualenv-20.26.4-py3-none-any.whl", hash = "sha256:48f2695d9809277003f30776d155615ffc11328e6a0a8c1f0ec80188d7874a55"}, + {file = "virtualenv-20.26.4.tar.gz", hash = "sha256:c17f4e0f3e6036e9f26700446f85c76ab11df65ff6d8a9cbfad9f71aabfcf23c"}, ] [package.dependencies] @@ -1121,4 +946,4 @@ jupyter = ["ipywidgets"] [metadata] lock-version = "2.0" python-versions = ">=3.7.0" -content-hash = "e69ef4afffb1a7f50ce363b497b4c306c11921177e66bc5844c1db8301a5e7f0" +content-hash = "4554a5f60982748a16d6914d652899f6d885b6fb7e72750634a37b8d4f5cb41e" diff --git a/pyproject.toml b/pyproject.toml index 5e0041810..43949e7bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,7 +44,7 @@ mypy = "^0.971" pytest-cov = "^3.0.0" attrs = "^21.4.0" pre-commit = "^2.17.0" -asv = "^0.6.4" +asv = "^0.5.1" importlib-metadata = { version = "*", python = "<3.8" } [build-system] diff --git a/rich/default_styles.py b/rich/default_styles.py index 031b94a13..28e8f6f94 100644 --- a/rich/default_styles.py +++ b/rich/default_styles.py @@ -120,6 +120,7 @@ "traceback.exc_type": Style(color="bright_red", bold=True), "traceback.exc_value": Style.null(), "traceback.offset": Style(color="bright_red", bold=True), + "traceback.error_range": Style(underline=True, bold=True, dim=False), "bar.back": Style(color="grey23"), "bar.complete": Style(color="rgb(249,38,114)"), "bar.finished": Style(color="rgb(114,156,31)"), diff --git a/rich/syntax.py b/rich/syntax.py index 4da6c3b7a..cff8fd235 100644 --- a/rich/syntax.py +++ b/rich/syntax.py @@ -221,6 +221,7 @@ class _SyntaxHighlightRange(NamedTuple): style: StyleType start: SyntaxPosition end: SyntaxPosition + style_before: bool = False class Syntax(JupyterMixin): @@ -534,7 +535,11 @@ def tokens_to_spans() -> Iterable[Tuple[str, Optional[Style]]]: return text def stylize_range( - self, style: StyleType, start: SyntaxPosition, end: SyntaxPosition + self, + style: StyleType, + start: SyntaxPosition, + end: SyntaxPosition, + style_before: bool = False, ) -> None: """ Adds a custom style on a part of the code, that will be applied to the syntax display when it's rendered. @@ -544,8 +549,11 @@ def stylize_range( style (StyleType): The style to apply. start (Tuple[int, int]): The start of the range, in the form `[line number, column index]`. end (Tuple[int, int]): The end of the range, in the form `[line number, column index]`. + style_before (bool): Apply the style before any existing styles. """ - self._stylized_ranges.append(_SyntaxHighlightRange(style, start, end)) + self._stylized_ranges.append( + _SyntaxHighlightRange(style, start, end, style_before) + ) def _get_line_numbers_color(self, blend: float = 0.3) -> Color: background_style = self._theme.get_background_style() + self.background_style @@ -785,7 +793,10 @@ def _apply_stylized_ranges(self, text: Text) -> None: newlines_offsets, stylized_range.end ) if start is not None and end is not None: - text.stylize(stylized_range.style, start, end) + if stylized_range.style_before: + text.stylize_before(stylized_range.style, start, end) + else: + text.stylize(stylized_range.style, start, end) def _process_code(self, code: str) -> Tuple[bool, str]: """ diff --git a/rich/traceback.py b/rich/traceback.py index fcefeb235..3bf5baa7b 100644 --- a/rich/traceback.py +++ b/rich/traceback.py @@ -1,7 +1,9 @@ +import inspect import linecache import os import sys from dataclasses import dataclass, field +from itertools import islice from traceback import walk_tb from types import ModuleType, TracebackType from typing import ( @@ -179,6 +181,7 @@ class Frame: name: str line: str = "" locals: Optional[Dict[str, pretty.Node]] = None + last_instruction: Optional[Tuple[Tuple[int, int], Tuple[int, int]]] = None @dataclass @@ -442,6 +445,35 @@ def get_locals( for frame_summary, line_no in walk_tb(traceback): filename = frame_summary.f_code.co_filename + + last_instruction: Optional[Tuple[Tuple[int, int], Tuple[int, int]]] + last_instruction = None + if sys.version_info >= (3, 11): + instruction_index = frame_summary.f_lasti // 2 + instruction_position = next( + islice( + frame_summary.f_code.co_positions(), + instruction_index, + instruction_index + 1, + ) + ) + ( + start_line, + end_line, + start_column, + end_column, + ) = instruction_position + if ( + start_line is not None + and end_line is not None + and start_column is not None + and end_column is not None + ): + last_instruction = ( + (start_line, start_column), + (end_line, end_column), + ) + if filename and not filename.startswith("<"): if not os.path.isabs(filename): filename = os.path.join(_IMPORT_CWD, filename) @@ -452,16 +484,20 @@ def get_locals( filename=filename or "?", lineno=line_no, name=frame_summary.f_code.co_name, - locals={ - key: pretty.traverse( - value, - max_length=locals_max_length, - max_string=locals_max_string, - ) - for key, value in get_locals(frame_summary.f_locals.items()) - } - if show_locals - else None, + locals=( + { + key: pretty.traverse( + value, + max_length=locals_max_length, + max_string=locals_max_string, + ) + for key, value in get_locals(frame_summary.f_locals.items()) + if not (inspect.isfunction(value) or inspect.isclass(value)) + } + if show_locals + else None + ), + last_instruction=last_instruction, ) append(frame) if frame_summary.f_locals.get("_rich_traceback_guard", False): @@ -711,6 +747,14 @@ def render_locals(frame: Frame) -> Iterable[ConsoleRenderable]: (f"\n{error}", "traceback.error"), ) else: + if frame.last_instruction is not None: + start, end = frame.last_instruction + syntax.stylize_range( + style="traceback.error_range", + start=start, + end=end, + style_before=True, + ) yield ( Columns( [ @@ -725,12 +769,12 @@ def render_locals(frame: Frame) -> Iterable[ConsoleRenderable]: if __name__ == "__main__": # pragma: no cover - from .console import Console - - console = Console() + install(show_locals=True) import sys - def bar(a: Any) -> None: # 这是对亚洲语言支持的测试。面对模棱两可的想法,拒绝猜测的诱惑 + def bar( + a: Any, + ) -> None: # 这是对亚洲语言支持的测试。面对模棱两可的想法,拒绝猜测的诱惑 one = 1 print(one / a) @@ -748,12 +792,6 @@ def foo(a: Any) -> None: bar(a) def error() -> None: - try: - try: - foo(0) - except: - slfkjsldkfj # type: ignore[name-defined] - except: - console.print_exception(show_locals=True) + foo(0) error() diff --git a/tests/test_traceback.py b/tests/test_traceback.py index 7f1525c28..ed80d1ba7 100644 --- a/tests/test_traceback.py +++ b/tests/test_traceback.py @@ -327,3 +327,34 @@ def level3(): assert len(frames) == expected_frames_length frame_names = [f.name for f in frames] assert frame_names == expected_frame_names + + +@pytest.mark.skipif( + sys.version_info.minor >= 11, reason="Not applicable after Python 3.11" +) +def test_traceback_finely_grained_missing() -> None: + """Before 3.11, the last_instruction should be None""" + try: + 1 / 0 + except: + traceback = Traceback() + last_instruction = traceback.trace.stacks[-1].frames[-1].last_instruction + assert last_instruction is None + + +@pytest.mark.skipif( + sys.version_info.minor < 11, reason="Not applicable before Python 3.11" +) +def test_traceback_finely_grained() -> None: + """Check that last instruction is populated.""" + try: + 1 / 0 + except: + traceback = Traceback() + last_instruction = traceback.trace.stacks[-1].frames[-1].last_instruction + assert last_instruction is not None + assert isinstance(last_instruction, tuple) + assert len(last_instruction) == 2 + start, end = last_instruction + print(start, end) + assert start[0] == end[0]