[QUESTION] Derive multiple C++ class template instantiations from common base in Python
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 18k
- Forks
- 2.3k
- Avg merge
- 5d 17h
- Merged PRs (30d)
- 10
Description
Does a canonical solution exist to derive multiple C++ class template instantiations from a common Python base class, and to factory-create the derived classes?
I am looking to bind this C++ code:
template <bool ReadWrite>
struct File {
File(std::string filename);
std::string read();
// Only enabled if ReadWrite is true:
void write(std::string content);
}
Ideally I would call it in Python like this:
readonly_file = File(mode='r')
type(readonly_file) # File or FileReadOnly
readwrite_file = File(mode='w')
type(readwrite_file) # File or FileReadWrite
I can bind the two template instantiations as separate classes without issue:
template <bool ReadWrite>
void bind_file(py::module& m, const std::string& suffix) {
auto file_binding = py::class_<File<false>>(m, ("File" + suffix).c_str())
.def("read", &File<ReadWrite>::read);
if constexpr (ReadWrite) {
file_binding.def("write", &File<ReadWrite>::write);
}
}
bind_file<false>(m, "ReadOnly");
bind_file<true>(m, "ReadWrite");
At this point I would have to use the FileReadOnly and FileReadWrite classes in Python. However, it is more common in Python code to use constructor arguments for things like this read-write flag (since everything is evaluated at runtime anyway in Python). These are the options I'm considering:
- Add a factory function named
Filethat returns an object of either class cast topy::objectbased on runtime arguments. However, it will show up as a function in Python, not as a class. TheFileReadOnlyandFileReadWriteclasses will have no relationship in Python. - Add a common base class in Python with a constructor that factory-creates the base classes. Is this even possible?
Further questions:
- Can I avoid exposing the individual
FileReadOnlyandFileReadWriteclasses altogether, only exposingFileto Python that changes behavior based on the constructor argument? - Can I avoid repeating the factory function for all possible constructors, i.e. just forward the remaining arguments (like
filenamehere) to the respective constructor?
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 with the issue's two C++ template bindings and the proposed Python constructor and factory APIs. Determine whether a canonical approach exists for runtime selection, common inheritance, and forwarding constructor arguments; done would be a documented, agreed-upon API pattern or a clear statement that the requested design is unsupported.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- api, developer-experience
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100