Skip to content

Commit 6c0be4b

Browse files
authored
Disallow .__call__() as workaround for non-named functions (#32460)
1 parent 699b56f commit 6c0be4b

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

doc/source/whatsnew/v1.1.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,7 @@ Reshaping
840840
- Bug in :func:`concat` was not allowing for concatenation of ``DataFrame`` and ``Series`` with duplicate keys (:issue:`33654`)
841841
- Bug in :func:`cut` raised an error when non-unique labels (:issue:`33141`)
842842
- Bug in :meth:`DataFrame.replace` casts columns to ``object`` dtype if items in ``to_replace`` not in values (:issue:`32988`)
843+
- Ensure only named functions can be used in :func:`eval()` (:issue:`32460`)
843844

844845
Sparse
845846
^^^^^^

pandas/core/computation/expr.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ def visit_Attribute(self, node, **kwargs):
641641

642642
def visit_Call(self, node, side=None, **kwargs):
643643

644-
if isinstance(node.func, ast.Attribute):
644+
if isinstance(node.func, ast.Attribute) and node.func.attr != "__call__":
645645
res = self.visit_Attribute(node.func)
646646
elif not isinstance(node.func, ast.Name):
647647
raise TypeError("Only named functions are supported")

pandas/tests/frame/test_query_eval.py

+21
Original file line numberDiff line numberDiff line change
@@ -1181,3 +1181,24 @@ def test_failing_character_outside_range(self, df):
11811181
def test_failing_hashtag(self, df):
11821182
with pytest.raises(SyntaxError):
11831183
df.query("`foo#bar` > 4")
1184+
1185+
def test_call_non_named_expression(self, df):
1186+
"""
1187+
Only attributes and variables ('named functions') can be called.
1188+
.__call__() is not an allowed attribute because that would allow
1189+
calling anything.
1190+
https://github.com/pandas-dev/pandas/pull/32460
1191+
"""
1192+
1193+
def func(*_):
1194+
return 1
1195+
1196+
funcs = [func] # noqa
1197+
1198+
df.eval("@func()")
1199+
1200+
with pytest.raises(TypeError, match="Only named functions are supported"):
1201+
df.eval("@funcs[0]()")
1202+
1203+
with pytest.raises(TypeError, match="Only named functions are supported"):
1204+
df.eval("@funcs[0].__call__()")

0 commit comments

Comments
 (0)