Skip to content

Commit

Permalink
Allow unsafe custom __getitem__ executions when allow unsafe executio…
Browse files Browse the repository at this point in the history
…ns is on
  • Loading branch information
davidhalter committed Jul 28, 2023
1 parent 8a4b079 commit 57aefed
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 5 deletions.
4 changes: 2 additions & 2 deletions jedi/inference/compiled/access.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,8 @@ def py__getitem__all_values(self):
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

Expand Down
5 changes: 4 additions & 1 deletion jedi/inference/compiled/value.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,10 @@ def _ensure_one_filter(self, is_instance):
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:
Expand Down
21 changes: 19 additions & 2 deletions test/test_api/test_interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)

0 comments on commit 57aefed

Please sign in to comment.