This PR addresses incorrect error handling logic for the containment operation in pytricia.c.
Demonstration of the bug in the current pytricia master branch (29ff816):
import pytricia
import traceback
pyt = pytricia.PyTricia(128)
try:
# this is the line that raises the exception:
if "42" in pyt:
pass
except Exception as e:
print("This one should be triggered")
print(e)
try:
print(len("hello"))
except Exception as e:
print("This one is triggered instead")
print(e)
traceback.print_exc()
Expected Output:
This one should be triggered
Invalid key type
5
Actual Output:
This one is triggered instead
<built-in function len> returned a result with an error set
ValueError: Invalid key type
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "test.py", line 15, in <module>
print(len("hello"))
SystemError: <built-in function len> returned a result with an error set
Determine if o contains value. If an item in o is equal to value, return 1, otherwise return 0. On error, return -1. This is equivalent to the Python expression value in o.
However, pytricia_contains currently returns 0 instead of -1 in the case of an error, and at the same time the call to _key_object_to_prefix raises a Python exception, which results in undefined Python exception handling behaviour. This PR fixes the issue.
This PR addresses incorrect error handling logic for the containment operation in pytricia.c.
Demonstration of the bug in the current pytricia master branch (
29ff816
):Expected Output:
Actual Output:
The Python C API documentation for
PySequence_Contains
says:However,
pytricia_contains
currently returns 0 instead of -1 in the case of an error, and at the same time the call to_key_object_to_prefix
raises a Python exception, which results in undefined Python exception handling behaviour. This PR fixes the issue.