Files
Paolo Tosco 2b4202867e Add Python modules to generate stubs and automatically patch docstrings (#6919)
* - added gen_rdkit_stubs Python module to generate rdkit-stubs
- added patch_rdkit_docstrings Python module to patch existing C++ sources to fix docstrings missing self parameter and add named parameters taken from C++ signatures where possible
- added rdkit-stubs/CMakeLists.txt to build rdkit-stubs as part of the RDKit build
- added an option to CMakeLists.txt to enable building rdkit-stubs as part of the RDKit build (defaults to OFF)

* fixed CMakeLists.txt, rdkit-stubs/CMakeLists.txt and a doctest

* - added missing cmp_func parameter
- fixed case with overloads with optional parameters
- do not trim params if expected_param_count == -1
- add dummy parameter names if we could not find any
- keep into account member functions when making up parameter names
- address __init__ and make_constructor __init__ functions
- fix incorrectly assigned staticmethods

* patched sources

* address residual few remarks

---------

Co-authored-by: ptosco <paolo.tosco@novartis.com>
2023-11-30 04:54:18 +01:00

135 lines
5.2 KiB
C++

//
// Copyright (C) 2018 Susan H. Leung
//
// @@ All Rights Reserved @@
// This file is part of the RDKit.
// The contents are covered by the terms of the BSD license
// which is included in the file license.txt, found at the root
// of the RDKit source tree.
//
#include <RDBoost/Wrap.h>
#include <GraphMol/RDKitBase.h>
#include <GraphMol/SmilesParse/SmartsWrite.h>
#include <GraphMol/MolStandardize/Metal.h>
namespace python = boost::python;
namespace {
class MetalDisconnectorWrap {
public:
MetalDisconnectorWrap(python::object options = python::object()) {
if (options.is_none()) {
md_.reset(new RDKit::MolStandardize::MetalDisconnector());
} else {
RDKit::MolStandardize::MetalDisconnectorOptions md_opts;
md_opts.splitGrignards =
python::extract<bool>(options.attr("splitGrignards"));
md_opts.splitAromaticC =
python::extract<bool>(options.attr("splitAromaticC"));
md_opts.adjustCharges =
python::extract<bool>(options.attr("adjustCharges"));
md_opts.removeHapticDummies =
python::extract<bool>(options.attr("removeHapticDummies"));
md_.reset(new RDKit::MolStandardize::MetalDisconnector(md_opts));
}
}
RDKit::ROMol *getMetalNof() { return md_->getMetalNof(); }
RDKit::ROMol *getMetalNon() { return md_->getMetalNon(); }
void setMetalNof(const RDKit::ROMol &mol) { md_->setMetalNof(mol); }
void setMetalNon(const RDKit::ROMol &mol) { md_->setMetalNon(mol); }
RDKit::ROMol *disconnect(const RDKit::ROMol &mol) {
return md_->disconnect(mol);
}
void disconnectInPlace(RDKit::ROMol &mol) {
return md_->disconnectInPlace(static_cast<RDKit::RWMol &>(mol));
}
private:
std::unique_ptr<RDKit::MolStandardize::MetalDisconnector> md_;
};
std::string getMetalNofHelper(MetalDisconnectorWrap &self) {
return RDKit::MolToSmarts(*(self.getMetalNof()));
}
std::string getMetalNonHelper(MetalDisconnectorWrap &self) {
return RDKit::MolToSmarts(*(self.getMetalNon()));
}
void setMetalNonHelper(MetalDisconnectorWrap &self, const RDKit::ROMol &mol) {
self.setMetalNon(mol);
}
void setMetalNofHelper(MetalDisconnectorWrap &self, const RDKit::ROMol &mol) {
self.setMetalNof(mol);
}
} // namespace
struct metal_wrapper {
static void wrap() {
python::scope().attr("__doc__") =
"Module containing functions for molecular standardization";
std::string docString = "Metal Disconnector Options";
python::class_<RDKit::MolStandardize::MetalDisconnectorOptions>(
"MetalDisconnectorOptions", docString.c_str(),
python::init<>(python::args("self")))
.def_readwrite(
"splitGrignards",
&RDKit::MolStandardize::MetalDisconnectorOptions::splitGrignards,
"Whether to split Grignard-type complexes. Default false.")
.def_readwrite(
"splitAromaticC",
&RDKit::MolStandardize::MetalDisconnectorOptions::splitAromaticC,
"Whether to split metal-aromatic C bonds. Default false.")
.def_readwrite(
"adjustCharges",
&RDKit::MolStandardize::MetalDisconnectorOptions::adjustCharges,
"Whether to adjust charges on ligand atoms. Default true.")
.def_readwrite("removeHapticDummies",
&RDKit::MolStandardize::MetalDisconnectorOptions::
removeHapticDummies,
"Whether to remove the dummy atoms representing haptic"
" bonds. Such dummies are bonded to the metal with a"
" bond that has the MolFileBondEndPts prop set."
" Default false.");
docString =
"a class to disconnect metals that are defined as covalently bonded to"
" non-metals";
python::class_<MetalDisconnectorWrap, boost::noncopyable>(
"MetalDisconnector", docString.c_str(),
python::init<python::optional<python::object>>(
(python::arg("self"), python::arg("options") = python::object())))
.add_property("MetalNof", &getMetalNofHelper,
"SMARTS defining the metals to disconnect if attached to "
"Nitrogen, Oxygen or Fluorine")
.add_property(
"MetalNon", &getMetalNonHelper,
"SMARTS defining the metals to disconnect other inorganic elements")
.def(
"SetMetalNon", &setMetalNonHelper,
(python::arg("self"), python::arg("mol")),
"Set the query molecule defining the metals to disconnect from other"
" inorganic elements.")
.def(
"SetMetalNof", &setMetalNofHelper,
(python::arg("self"), python::arg("mol")),
"Set the query molecule defining the metals to disconnect if attached"
" to Nitrogen, Oxygen or Fluorine.")
.def("Disconnect", &MetalDisconnectorWrap::disconnect,
(python::arg("self"), python::arg("mol")),
"performs the disconnection",
python::return_value_policy<python::manage_new_object>())
.def("DisconnectInPlace", &MetalDisconnectorWrap::disconnectInPlace,
(python::arg("self"), python::arg("mol")),
"performs the disconnection, modifies the input molecule");
}
};
void wrap_metal() { metal_wrapper::wrap(); }