Wrapping empty list works, wrapping empty set results in a TypeError
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 18k
- Forks
- 2.3k
- Avg merge
- 5d 17h
- Merged PRs (30d)
- 10
Description
Issue description
I am trying to wrap a C++ function which takes as input a set with pybind11. If the set is non-empty, wrapping works fine,
while if the set is empty I get errors such as
TypeError: print_set(): incompatible function arguments. The following argument types are supported:
1. (arg0: Set[int]) -> None
I realize that the type int cannot be deduced from an empty set. However, wrapping of empty lists succeeds.
Is it possible to extend set conversion to the case of empty set?
Thanks.
Reproducible example code
import cppimport
def compile_module():
cpp_code = """
<%
setup_pybind11(cfg)
%>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <iostream>
void print_list(const std::vector<int> & list){
std::cout << "List: ";
for (auto& i: list) {
std::cout << i << " ";
}
std::cout << std::endl;
}
void print_set(const std::set<int> & set){
std::cout << "Set: ";
for (auto& i: set) {
std::cout << i << " ";
}
std::cout << std::endl;
}
void print_list_of_lists(const std::vector<std::vector<int>> & lists){
std::cout << "Lists: ";
for (auto & list: lists) {
for (auto& i: list) {
std::cout << i << " ";
}
std::cout << ", ";
}
std::cout << std::endl;
}
void print_list_of_sets(const std::vector<std::set<int>> & sets){
std::cout << "Sets: ";
for (auto & set: sets) {
for (auto& i: set) {
std::cout << i << " ";
}
std::cout << ", ";
}
std::cout << std::endl;
}
PYBIND11_MODULE(pybind_tester, m)
{
m.def("print_list", &print_list);
m.def("print_set", &print_set);
m.def("print_list_of_lists", &print_list_of_lists);
m.def("print_list_of_sets", &print_list_of_sets);
}
"""
open("pybind_tester.cpp", "w").write(cpp_code)
return cppimport.imp("pybind_tester")
module = compile_module()
# Print non-empty containers
module.print_list([8, 9])
module.print_set({1, 2})
# Print empty containers
module.print_list([])
try:
module.print_set({})
except TypeError:
print("Set: failure")
else:
raise RuntimeError("Expecting failure")
# Print list of containers with all non-empty elements
module.print_list_of_lists([[8, 9], [1, 2, 3], [4]])
module.print_list_of_sets([{1, 2}, {6}, {4, 3}])
# Print list of containers with all non-empty elements
module.print_list_of_lists([[8, 9], [1, 2, 3], [4], []])
try:
module.print_list_of_sets([{1, 2}, {6}, {4, 3}, {}])
except TypeError:
print("Sets: failure")
else:
raise RuntimeError("Expecting failure")
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the reproducible Python/C++ example and inspect the STL conversion path included through pybind11/stl.h, comparing empty list and empty set handling. Done means an empty set is accepted for a set[int] argument, including an empty nested set, without changing the existing non-empty behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- api
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100