Skip to content

Commit ee1b962

Browse files
committed
Fix the python 3.13 FrameLocalsProxy issue PEP 667
1 parent 5565c7b commit ee1b962

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

src/TableFunctions/TableFunctionPython.cpp

+24-8
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,39 @@ py::object findQueryableObj(const std::string & var_name)
4040

4141
while (!current_frame.is_none())
4242
{
43-
auto local_dict = py::reinterpret_borrow<py::dict>(current_frame.attr("f_locals"));
44-
auto global_dict = py::reinterpret_borrow<py::dict>(current_frame.attr("f_globals"));
43+
// Get f_locals and f_globals
44+
py::object locals_obj = current_frame.attr("f_locals");
45+
py::object globals_obj = current_frame.attr("f_globals");
4546

46-
for (const auto & dict : {local_dict, global_dict})
47+
// For each namespace (locals and globals)
48+
for (const auto & namespace_obj : {locals_obj, globals_obj})
4749
{
48-
if (dict.contains(var_name))
50+
// Use Python's __contains__ method to check if the key exists
51+
// This works with both regular dicts and FrameLocalsProxy (Python 3.13+)
52+
if (py::bool_(namespace_obj.attr("__contains__")(var_name)))
4953
{
50-
py::object obj = dict[var_name.data()];
51-
if (isInheritsFromPyReader(obj) || isPandasDf(obj) || isPyarrowTable(obj) || hasGetItem(obj))
52-
return obj;
54+
py::object obj;
55+
try
56+
{
57+
// Get the object using Python's indexing syntax
58+
obj = namespace_obj[py::cast(var_name)];
59+
if (isInheritsFromPyReader(obj) || isPandasDf(obj) || isPyarrowTable(obj) || hasGetItem(obj))
60+
{
61+
return obj;
62+
}
63+
}
64+
catch (const py::error_already_set &)
65+
{
66+
continue; // If getting the value fails, continue to the next namespace
67+
}
5368
}
5469
}
5570

71+
// Move to the parent frame
5672
current_frame = current_frame.attr("f_back");
5773
}
5874

59-
// not found
75+
// Object not found
6076
return py::none();
6177
}
6278

0 commit comments

Comments
 (0)