Narrow source positions for exceptions during pattern matching
@iritkatriel đang làm issue này rồi.
Từ ngày 30/9/2022.
- Ngôn ngữ chính
- Python
- Star
- 77.2k
- Fork
- 36k
- Chỉ số merge pull request
- Chỉ số pull request đang chờ
Mô tả
The source range in the traceback is to wide in some cases, if an exception is thrown during matching of a pattern.
The Ranges
example for attribute lookup:
class A:
def __getattr__(self, name):
assert name[0] == "a"
return 5
match A():
case A(apple=5, banana=7):
print("hi")
output (Python 3.11.0rc2+):
Traceback (most recent call last):
File "/home/frank/projects/cpython/match_test.py", line 8, in <module>
case A(apple=5, banana=7):
^^^^^^^^^^^^^^^^^^^^
File "/home/frank/projects/cpython/match_test.py", line 3, in __getattr__
assert name[0] == "a"
AssertionError
Annotating only the source positions where the attribute check failed (banana=7) would make the traceback easier to read.
The same problem exists for positional matching:
class A:
__match_args__ = ("apple", "banana")
def __getattr__(self, name):
assert name == "apple"
match A():
case A(5, 7):
print("hi")
output (Python 3.11.0rc2+):
Traceback (most recent call last):
File "/home/frank/projects/cpython/match_test2.py", line 9, in <module>
case A(5, 7):
^^^^^^^
File "/home/frank/projects/cpython/match_test2.py", line 5, in __getattr__
assert name == "apple"
AssertionError
Equality checks are handled better:
class NeverEqual:
def __eq__(self, other):
assert other==5
class A:
def __init__(self):
self.a = NeverEqual()
self.b = 3
match A():
case A(a=5|3, b=3):
print("hi")
output (Python 3.11.0rc2+):
Traceback (most recent call last):
File "/home/frank/projects/cpython/match_test3.py", line 13, in <module>
case A(a=5|3, b=3):
^
File "/home/frank/projects/cpython/match_test3.py", line 3, in __eq__
assert other==5
AssertionError
Instance checks are represented in the same way:
class MetaB(type):
def __instancecheck__(self, instance):
assert False, "do not use me"
class B(metaclass=MetaB):
pass
class A:
def __init__(self):
self.a = 5
self.b = 3
match A():
case A(a=5, b=2|B()):
print("hi")
output (Python 3.11.0rc2+):
Traceback (most recent call last):
File "/home/frank/projects/cpython/match_test4.py", line 17, in <module>
case A(a=5, b=2|B()):
^^^
File "/home/frank/projects/cpython/match_test4.py", line 3, in __instancecheck__
assert False, "do not use me"
AssertionError: do not use me
Problem for the User
Consistent source ranges would improve the readability of the tracebacks.
Is it possible to highlight always only the failing Pattern (with attribute name if given) for failing attribute access?
example:
case A(a=5):
^^^
case A(a=B()):
^^^^^
case A(5):
^
case A(5|B()):
^^^^^
Instance checks and equality tests are already handled well:
case A(a=5):
^
case A(a=B()):
^^^
case A(5):
^
case A(B()):
^^^
case A(5|B())
^^^
Problem for libraries
Libraries are using the source ranges for all sorts of functionality.
Executing for example is using this ranges (for the new 3.11 support) to map from instructions back to ast-nodes. Useful ranges are here required to map to useful ast-nodes.
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Đánh giá
Issue này chưa được đánh giá.