mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-03 21:44:30 +08:00
Use std::string_view for property keys (#8844)
* string_view props API * wip * fix leak * add string_view to swig * fix comment * add backwards incompatibilty note * fix rebase issue --------- Co-authored-by: Greg Landrum <greg.landrum@gmail.com>
This commit is contained in:
committed by
GitHub
parent
ad1fcb5b7b
commit
7d1e662bc7
@@ -28,8 +28,9 @@
|
||||
#include "list_indexing_suite.hpp"
|
||||
#include <RDGeneral/BoostEndInclude.h>
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <RDGeneral/Exceptions.h>
|
||||
|
||||
namespace python = boost::python;
|
||||
@@ -322,47 +323,6 @@ struct iterable_converter {
|
||||
}
|
||||
};
|
||||
|
||||
/// Simple Boost.Python custom converter from pathlib.Path to std::string
|
||||
template <typename T = std::string>
|
||||
struct path_converter {
|
||||
path_converter() {
|
||||
python::converter::registry::push_back(&path_converter::convertible,
|
||||
&path_converter::construct,
|
||||
boost::python::type_id<T>());
|
||||
}
|
||||
|
||||
/// Check PyObject is a pathlib.Path
|
||||
static void *convertible(PyObject *object) {
|
||||
// paranoia
|
||||
if (object == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
python::object boost_object(python::handle<>(python::borrowed(object)));
|
||||
|
||||
std::string object_classname = boost::python::extract<std::string>(
|
||||
boost_object.attr("__class__").attr("__name__"));
|
||||
// pathlib.Path is always specialized to the below derived classes
|
||||
if (object_classname == "WindowsPath" || object_classname == "PosixPath") {
|
||||
return object;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// Construct a std::string from pathlib.Path using its own __str__ attribute
|
||||
static void construct(
|
||||
PyObject *object,
|
||||
boost::python::converter::rvalue_from_python_stage1_data *data) {
|
||||
void *storage =
|
||||
((boost::python::converter::rvalue_from_python_storage<T> *)data)
|
||||
->storage.bytes;
|
||||
python::object boost_object{python::handle<>{python::borrowed(object)}};
|
||||
new (storage)
|
||||
T{boost::python::extract<std::string>{boost_object.attr("__str__")()}};
|
||||
data->convertible = storage;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// allows rdkit objects to be pickled.
|
||||
struct rdkit_pickle_suite : python::pickle_suite {
|
||||
|
||||
@@ -234,6 +234,81 @@ struct python_ostream_wrapper {
|
||||
};
|
||||
|
||||
void seedRNG(unsigned int seed) { std::srand(seed); }
|
||||
|
||||
/// Simple Boost.Python custom converter from pathlib.Path to std::string
|
||||
template <typename T = std::string>
|
||||
struct path_converter {
|
||||
path_converter() {
|
||||
python::converter::registry::push_back(&path_converter::convertible,
|
||||
&path_converter::construct,
|
||||
boost::python::type_id<T>());
|
||||
}
|
||||
|
||||
/// Check PyObject is a pathlib.Path
|
||||
static void *convertible(PyObject *object) {
|
||||
// paranoia
|
||||
if (object == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
python::object boost_object(python::handle<>(python::borrowed(object)));
|
||||
|
||||
std::string object_classname = boost::python::extract<std::string>(
|
||||
boost_object.attr("__class__").attr("__name__"));
|
||||
// pathlib.Path is always specialized to the below derived classes
|
||||
if (object_classname == "WindowsPath" || object_classname == "PosixPath") {
|
||||
return object;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// Construct a std::string from pathlib.Path using its own __str__ attribute
|
||||
static void construct(
|
||||
PyObject *object,
|
||||
boost::python::converter::rvalue_from_python_stage1_data *data) {
|
||||
void *storage =
|
||||
((boost::python::converter::rvalue_from_python_storage<T> *)data)
|
||||
->storage.bytes;
|
||||
python::object boost_object{python::handle<>{python::borrowed(object)}};
|
||||
new (storage)
|
||||
T{boost::python::extract<std::string>{boost_object.attr("__str__")()}};
|
||||
data->convertible = storage;
|
||||
}
|
||||
};
|
||||
|
||||
/// Convert a Python str to a std::string_view
|
||||
template <typename T = std::string_view>
|
||||
struct string_view_converter {
|
||||
string_view_converter() {
|
||||
python::converter::registry::push_back(&string_view_converter::convertible,
|
||||
&string_view_converter::construct,
|
||||
boost::python::type_id<T>());
|
||||
}
|
||||
|
||||
/// Check PyObject is a str
|
||||
static void *convertible(PyObject *object) {
|
||||
if (object != nullptr && PyUnicode_Check(object)) {
|
||||
return object;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// Construct a std::string_view from the internal string of the PyObject.
|
||||
/// This shouldn´t fail, as we block the Python thread until the C++ code
|
||||
/// returns, so the PyObject and the internal string should remain valid.
|
||||
static void construct(
|
||||
PyObject *object,
|
||||
boost::python::converter::rvalue_from_python_stage1_data *data) {
|
||||
const char *tmp = PyUnicode_AsUTF8(object);
|
||||
|
||||
void *storage =
|
||||
((boost::python::converter::rvalue_from_python_storage<T> *)data)
|
||||
->storage.bytes;
|
||||
new (storage) T{tmp};
|
||||
data->convertible = storage;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
BOOST_PYTHON_MODULE(rdBase) {
|
||||
@@ -256,6 +331,7 @@ BOOST_PYTHON_MODULE(rdBase) {
|
||||
RegisterVectorConverter<std::pair<int, int>>("MatchTypeVect");
|
||||
|
||||
path_converter();
|
||||
string_view_converter();
|
||||
|
||||
RegisterListConverter<int>();
|
||||
RegisterListConverter<std::vector<int>>();
|
||||
|
||||
Reference in New Issue
Block a user