mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 14:34:31 +08:00
Allow unsafe custom __getitem__ executions when allow unsafe executions is on
This commit is contained in:
@@ -230,8 +230,8 @@ class DirectObjectAccess:
|
|||||||
return [annotation]
|
return [annotation]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def py__simple_getitem__(self, index):
|
def py__simple_getitem__(self, index, *, safe=True):
|
||||||
if type(self._obj) not in ALLOWED_GETITEM_TYPES:
|
if safe and type(self._obj) not in ALLOWED_GETITEM_TYPES:
|
||||||
# Get rid of side effects, we won't call custom `__getitem__`s.
|
# Get rid of side effects, we won't call custom `__getitem__`s.
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
@@ -162,7 +162,10 @@ class CompiledValue(Value):
|
|||||||
def py__simple_getitem__(self, index):
|
def py__simple_getitem__(self, index):
|
||||||
with reraise_getitem_errors(IndexError, KeyError, TypeError):
|
with reraise_getitem_errors(IndexError, KeyError, TypeError):
|
||||||
try:
|
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:
|
except AttributeError:
|
||||||
return super().py__simple_getitem__(index)
|
return super().py__simple_getitem__(index)
|
||||||
if access is None:
|
if access is None:
|
||||||
|
|||||||
@@ -613,12 +613,12 @@ def test_dict_getitem(code, types):
|
|||||||
#('for x in dunder: x', 'str'),
|
#('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
|
from typing import Iterator
|
||||||
|
|
||||||
class DunderCls:
|
class DunderCls:
|
||||||
def __getitem__(self, key) -> int:
|
def __getitem__(self, key) -> int:
|
||||||
pass
|
return 1
|
||||||
|
|
||||||
def __iter__(self, key) -> Iterator[str]:
|
def __iter__(self, key) -> Iterator[str]:
|
||||||
pass
|
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"'])
|
_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)
|
||||||
|
|||||||
Reference in New Issue
Block a user