##// END OF EJS Templates
Add more tests
krassowski -
Show More
@@ -60,7 +60,8 b' MayHaveGetattr = Union[HasGetAttr, DoesNotHaveGetAttr]'
60 def _unbind_method(func: Callable) -> Union[Callable, None]:
60 def _unbind_method(func: Callable) -> Union[Callable, None]:
61 """Get unbound method for given bound method.
61 """Get unbound method for given bound method.
62
62
63 Returns None if cannot get unbound method."""
63 Returns None if cannot get unbound method, or method is already unbound.
64 """
64 owner = getattr(func, "__self__", None)
65 owner = getattr(func, "__self__", None)
65 owner_class = type(owner)
66 owner_class = type(owner)
66 name = getattr(func, "__name__", None)
67 name = getattr(func, "__name__", None)
@@ -214,7 +215,7 b' class SelectivePolicy(EvaluationPolicy):'
214
215
215 accept = False
216 accept = False
216
217
217 # Many objects do not have `__getattr__`, this is fine
218 # Many objects do not have `__getattr__`, this is fine.
218 if has_original_attr is None and has_original_attribute:
219 if has_original_attr is None and has_original_attribute:
219 accept = True
220 accept = True
220 else:
221 else:
@@ -234,9 +235,10 b' class SelectivePolicy(EvaluationPolicy):'
234 if not is_property:
235 if not is_property:
235 return True
236 return True
236
237
237 # Properties in allowed types are ok
238 # Properties in allowed types are ok (although we do not include any
239 # properties in our default allow list currently).
238 if type(value) in self.allowed_getattr:
240 if type(value) in self.allowed_getattr:
239 return True
241 return True # pragma: no cover
240
242
241 # Properties in subclasses of allowed types may be ok if not changed
243 # Properties in subclasses of allowed types may be ok if not changed
242 for module_name, *access_path in self.allowed_getattr_external:
244 for module_name, *access_path in self.allowed_getattr_external:
@@ -22,7 +22,6 b' unsafe = partial(create_context, "unsafe")'
22 dangerous = partial(create_context, "dangerous")
22 dangerous = partial(create_context, "dangerous")
23
23
24 LIMITED_OR_HIGHER = [limited, unsafe, dangerous]
24 LIMITED_OR_HIGHER = [limited, unsafe, dangerous]
25
26 MINIMAL_OR_HIGHER = [minimal, *LIMITED_OR_HIGHER]
25 MINIMAL_OR_HIGHER = [minimal, *LIMITED_OR_HIGHER]
27
26
28
27
@@ -41,6 +40,39 b' def module_not_installed(module: str):'
41 sys.modules[module] = to_restore
40 sys.modules[module] = to_restore
42
41
43
42
43 def test_external_not_installed():
44 """
45 Because attribute check requires checking if object is not of allowed
46 external type, this tests logic for absence of external module.
47 """
48
49 class Custom:
50 def __init__(self):
51 self.test = 1
52
53 def __getattr__(self, key):
54 return key
55
56 with module_not_installed("pandas"):
57 context = limited(x=Custom())
58 with pytest.raises(GuardRejection):
59 guarded_eval("x.test", context)
60
61
62 @dec.skip_without("pandas")
63 def test_external_changed_api(monkeypatch):
64 """Check that the execution rejects if external API changed paths"""
65 import pandas as pd
66
67 series = pd.Series([1], index=["a"])
68
69 with monkeypatch.context() as m:
70 m.delattr(pd, "Series")
71 context = limited(data=series)
72 with pytest.raises(GuardRejection):
73 guarded_eval("data.iloc[0]", context)
74
75
44 @dec.skip_without("pandas")
76 @dec.skip_without("pandas")
45 def test_pandas_series_iloc():
77 def test_pandas_series_iloc():
46 import pandas as pd
78 import pandas as pd
@@ -496,6 +528,7 b' def test_unbind_method():'
496 x = X()
528 x = X()
497 assert _unbind_method(x.index) is X.index
529 assert _unbind_method(x.index) is X.index
498 assert _unbind_method([].index) is list.index
530 assert _unbind_method([].index) is list.index
531 assert _unbind_method(list.index) is None
499
532
500
533
501 def test_assumption_instance_attr_do_not_matter():
534 def test_assumption_instance_attr_do_not_matter():
General Comments 0
You need to be logged in to leave comments. Login now