Allow unsafe custom __getitem__ executions when allow unsafe executions is on

This commit is contained in:
Dave Halter
2023-07-29 00:33:09 +02:00
parent 8a4b079d0f
commit 57aefed6ea
3 changed files with 25 additions and 5 deletions

View File

@@ -230,8 +230,8 @@ class DirectObjectAccess:
return [annotation]
return None
def py__simple_getitem__(self, index):
if type(self._obj) not in ALLOWED_GETITEM_TYPES:
def py__simple_getitem__(self, index, *, safe=True):
if safe and type(self._obj) not in ALLOWED_GETITEM_TYPES:
# Get rid of side effects, we won't call custom `__getitem__`s.
return None

View File

@@ -162,7 +162,10 @@ class CompiledValue(Value):
def py__simple_getitem__(self, index):
with reraise_getitem_errors(IndexError, KeyError, TypeError):
try:
access = self.access_handle.py__simple_getitem__(index)
access = self.access_handle.py__simple_getitem__(
index,
safe=not self.inference_state.allow_unsafe_executions
)
except AttributeError:
return super().py__simple_getitem__(index)
if access is None:

View File

@@ -613,12 +613,12 @@ def test_dict_getitem(code, types):
#('for x in dunder: x', 'str'),
]
)
def test_dunders(class_is_findable, code, expected):
def test_dunders(class_is_findable, code, expected, allow_unsafe_getattr):
from typing import Iterator
class DunderCls:
def __getitem__(self, key) -> int:
pass
return 1
def __iter__(self, key) -> Iterator[str]:
pass
@@ -838,3 +838,20 @@ def test_nested__getitem__():
_assert_interpreter_complete('d["foo"]["ba', locals(), ['"bar"'])
_assert_interpreter_complete('(d["foo"])["ba', locals(), ['"bar"'])
_assert_interpreter_complete('((d["foo"]))["ba', locals(), ['"bar"'])
@pytest.mark.parametrize('class_is_findable', [False, True])
def test_custom__getitem__(class_is_findable, allow_unsafe_getattr):
class CustomGetItem:
def __getitem__(self, x: int):
return "asdf"
if not class_is_findable:
CustomGetItem.__name__ = "something_somewhere"
namespace = {'c': CustomGetItem()}
if not class_is_findable and not allow_unsafe_getattr:
expected = []
else:
expected = ['upper']
_assert_interpreter_complete('c["a"].up', namespace, expected)