Skip to content

Commit 0ac3571

Browse files
committed
test-completer-trust
1 parent 90d946a commit 0ac3571

1 file changed

Lines changed: 50 additions & 0 deletions

File tree

tests/test_completer.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1516,6 +1516,56 @@ def __getattr__(self, attr):
15161516
_, matches = complete(line_buffer="unsafe_list_factory.example.")
15171517
self.assertNotIn(".append", matches)
15181518

1519+
def test_completion_allow_subclass_of_trusted_module(self):
1520+
factory_code = textwrap.dedent(
1521+
"""
1522+
class ListFactory:
1523+
def __getattr__(self, attr):
1524+
return []
1525+
"""
1526+
)
1527+
trusted_lib = types.ModuleType("my.trusted.lib")
1528+
sys.modules["my.trusted.lib"] = trusted_lib
1529+
exec(factory_code, trusted_lib.__dict__)
1530+
1531+
ip = get_ipython()
1532+
# Create a subclass in __main__ (untrusted namespace)
1533+
subclass_code = textwrap.dedent(
1534+
"""
1535+
class SubclassFactory(trusted_lib.ListFactory):
1536+
pass
1537+
"""
1538+
)
1539+
ip.user_ns["trusted_lib"] = trusted_lib
1540+
exec(subclass_code, ip.user_ns)
1541+
ip.user_ns["subclass_factory"] = ip.user_ns["SubclassFactory"]()
1542+
complete = ip.Completer.complete
1543+
with (
1544+
evaluation_policy("limited", allowed_getattr_external={"my.trusted.lib"}),
1545+
jedi_status(False),
1546+
):
1547+
_, matches = complete(line_buffer="subclass_factory.example.")
1548+
self.assertIn(".append", matches)
1549+
1550+
# Test that overriding __getattr__ in subclass in untrusted namespace prevents completion
1551+
overriding_subclass_code = textwrap.dedent(
1552+
"""
1553+
class OverridingSubclass(trusted_lib.ListFactory):
1554+
def __getattr__(self, attr):
1555+
return {}
1556+
"""
1557+
)
1558+
exec(overriding_subclass_code, ip.user_ns)
1559+
ip.user_ns["overriding_factory"] = ip.user_ns["OverridingSubclass"]()
1560+
1561+
with (
1562+
evaluation_policy("limited", allowed_getattr_external={"my.trusted.lib"}),
1563+
jedi_status(False),
1564+
):
1565+
_, matches = complete(line_buffer="overriding_factory.example.")
1566+
self.assertNotIn(".append", matches)
1567+
self.assertNotIn(".keys", matches)
1568+
15191569
def test_policy_warnings(self):
15201570
with self.assertWarns(
15211571
UserWarning,

0 commit comments

Comments
 (0)