Files
rdkit/Code/GraphMol/Wrap/rdchem.cpp
Ric a6b26253ff Fix (most of) mem problems (#2123)
* do not use new on loggers

* del pointers in testDistGeom

* Update Dict hasNonPOD status on bulk update

* delete new Dicts in memtest1.cpp

* fixes in MolSuppliers and testFMCS

* PeriodicTable singleton as unique_ptr

* fix EEM_arrays leak

* fix leaks in testPBF

* fix ParamCollection leak in test UFF

* fix leaks in MMFF

* clear prop dict before read in in pickler

* fix leaks in testFreeSASA

* fix leaks in test3D

* modernize Dict.h & SmilesParse.cpp

* fix leaks in testQuery

* fix leaks in testCrystalFF

* fix leaks in cxsmilesTest

* fix leaks in Catalog & mol cat test

* fix leaks in ShapeUtils & tests

* fix leaks in testSubgraphs1

* fix leaks testFingerprintGenerators

* fix leaks in Catalog/FilterCatalog

* fix leaks in graphmolqueryTest

* these changes reduce bison parse leaks

* fixed leaks in testChirality.cpp

* fix leaks + 2 tests in testMolWriter

* fix 4m leaks in substructLibraryTest

* small improvements to molTautomerTest; still leaks

* fix leaks in testRGroupDecomp

* fix leaks in test; parser still leaks

* fix leaks in itertest

* fix 4m leaks in testDepictor

* fixes in smatest; still leaking due to parser

* fixes in testSLNParse; still leaking due to parser

* flex/bison: always add atoms with ownership; smarts error cleanup

* fix leaks in testReaction

* fix leaks in testSubstructMatch

* fix leaks in resMolSupplierTest

* fix leaks in testChemTransforms + bug in ChemTransforms

* fix leaks in testPickler

* fix leaks in testMolTransform

* fix leaks in testFragCatalog

* fix leak in testSLNParse. Still leaks due to Smiles

* fixed most leaks in testMolSupplier

* pre bison fix

* fix some atom & bond parse problems; others still fail

* bison smiles & smarts, atoms & bonds more or less fixed

* fix leaks in molopstest.cpp

* fix leaks in testFingerprints, MACCS.cpp & AtomPairs.cpp

* fix leaks in moldraw2Dtest1

* fix leaks in testDescriptors

* fix leaks in testInchi

* fix leaks in testUFFForceFieldHelpers

* fix leaks in hanoiTest & new_canon.h

* fix leaks in testMMFFForceField

* fix leaks in graphmolTest1

* fix leaks in testMMFFForceFieldHelpers

* fix leaks in testDistGeomHelpers

* fix leaks in testMolAlign

* initialize occupancy & temp facto with default values

* fix leak in TautomerTransform

* updated suppressions

* fix testStructChecker

* fix logging & py tests

* fix TautomerTransform class/struct issue

* remove misplaced delete in testSLNParse

* deinit in testAvalonLib1

* fix Avalon-triggered(?) bug in StructChecker/Pattern.cpp

* fix random testMolWriter/Supplier fails

- diversify output file names to avoid clashing.
- unify Writers close/destruct behavior.
- flushing/closing in tests.

* use reset in FFs Params.cpp

* comments on testMMFFForceField

* unrequired 'if's added to mol suppliers

* correct cast in FilterCatalog.h

* use unique_ptr in MACCS Patterns

* remove unrequred if in new_canon

* update & move suppressions
2018-10-29 14:33:26 +00:00

201 lines
6.0 KiB
C++

// $Id$
//
// Copyright (C) 2003-2006 Rational Discovery LLC
//
// @@ 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.
//
#define PY_ARRAY_UNIQUE_SYMBOL rdchem_array_API
#include <RDBoost/Wrap.h>
#include "rdchem.h"
#include <GraphMol/RDKitBase.h>
#include <GraphMol/SanitException.h>
#include <RDBoost/import_array.h>
#include <RDBoost/iterator_next.h>
#ifdef RDK_THREADSAFE_SSS
// Thread local storage for output buffer for RDKit Logging
#include <thread>
#endif
#include <sstream>
#include <utility>
#include "seqs.hpp"
namespace python = boost::python;
using namespace RDKit;
namespace RDKit {
void tossit() { throw IndexErrorException(1); }
}
void rdExceptionTranslator(RDKit::ConformerException const &x) {
RDUNUSED_PARAM(x);
PyErr_SetString(PyExc_ValueError, "Bad Conformer Id");
}
void rdSanitExceptionTranslator(RDKit::MolSanitizeException const &x) {
std::ostringstream ss;
ss << "Sanitization error: " << x.message();
PyErr_SetString(PyExc_ValueError, ss.str().c_str());
}
void wrap_table();
void wrap_atom();
void wrap_conformer();
void wrap_bond();
void wrap_stereogroup();
void wrap_mol();
void wrap_ringinfo();
void wrap_EditableMol();
void wrap_monomerinfo();
void wrap_resmolsupplier();
void wrap_molbundle();
struct PySysErrWrite : std::ostream, std::streambuf {
std::string prefix;
PySysErrWrite(std::string prefix)
: std::ostream(this), prefix(std::move(prefix)) {}
int overflow(int c) override {
write(c);
return 0;
}
#ifdef RDK_THREADSAFE_SSS
void write(char c) { // enable thread safe logging
static thread_local std::string buffer = "";
buffer += c;
if (c == '\n') {
// Python IO is not thread safe, so grab the GIL
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
PySys_WriteStderr("%s", (prefix + buffer).c_str());
PyGILState_Release(gstate);
buffer.clear();
}
}
#else
std::string buffer; // unlimited! flushes in endl
void write(char c) {
buffer += c;
if (c == '\n') {
PySys_WriteStderr("%s", (prefix + buffer).c_str());
buffer.clear();
}
}
#endif
};
void RDLogError(const std::string &msg) {
NOGIL gil;
BOOST_LOG(rdErrorLog) << msg.c_str() << std::endl;
}
void RDLogWarning(const std::string &msg) {
NOGIL gil;
BOOST_LOG(rdWarningLog) << msg.c_str() << std::endl;
}
void WrapLogs() {
static PySysErrWrite debug("RDKit DEBUG: ");
static PySysErrWrite error("RDKit ERROR: ");
static PySysErrWrite info("RDKit INFO: ");
static PySysErrWrite warning("RDKit WARNING: ");
if (!rdDebugLog || !rdInfoLog || !rdErrorLog || !rdWarningLog) {
RDLog::InitLogs();
}
if (rdDebugLog != nullptr) rdDebugLog->SetTee(debug);
if (rdInfoLog != nullptr) rdInfoLog->SetTee(info);
if (rdErrorLog != nullptr) rdErrorLog->SetTee(error);
if (rdWarningLog != nullptr) rdWarningLog->SetTee(warning);
}
BOOST_PYTHON_MODULE(rdchem) {
python::scope().attr("__doc__") =
"Module containing the core chemistry functionality of the RDKit";
RegisterListConverter<RDKit::Atom *>();
RegisterListConverter<RDKit::Bond *>();
rdkit_import_array();
python::register_exception_translator<RDKit::MolSanitizeException>(
&rdSanitExceptionTranslator);
python::def("WrapLogs", WrapLogs,
"Wrap the internal RDKit streams so they go to python's "
"SysStdErr");
python::def("LogWarningMsg", RDLogWarning,
"Log a warning message to the RDKit warning logs");
python::def("LogErrorMsg", RDLogError,
"Log a warning message to the RDKit error logs");
//*********************************************
//
// Utility Classes
//
//*********************************************
python::class_<AtomIterSeq>(
"_ROAtomSeq",
"Read-only sequence of atoms, not constructable from Python.",
python::no_init)
.def("__iter__", &AtomIterSeq::__iter__,
python::return_internal_reference<
1, python::with_custodian_and_ward_postcall<0, 1>>())
.def(NEXT_METHOD, &AtomIterSeq::next,
python::return_value_policy<python::reference_existing_object>())
.def("__len__", &AtomIterSeq::len)
.def("__getitem__", &AtomIterSeq::get_item,
python::return_value_policy<python::reference_existing_object>());
python::class_<QueryAtomIterSeq>("_ROQAtomSeq",
"Read-only sequence of atoms matching a "
"query, not constructable from Python.",
python::no_init)
.def("__iter__", &QueryAtomIterSeq::__iter__,
python::return_internal_reference<
1, python::with_custodian_and_ward_postcall<0, 1>>())
.def(NEXT_METHOD, &QueryAtomIterSeq::next,
python::return_value_policy<python::reference_existing_object>())
.def("__len__", &QueryAtomIterSeq::len)
.def("__getitem__", &QueryAtomIterSeq::get_item,
python::return_value_policy<python::reference_existing_object>());
python::class_<BondIterSeq>(
"_ROBondSeq",
"Read-only sequence of bonds, not constructable from Python.",
python::no_init)
// FIX: we ought to be able to expose an iteration interface
.def("__len__", &BondIterSeq::len)
.def("__getitem__", &BondIterSeq::get_item,
python::return_value_policy<python::reference_existing_object>());
//*********************************************
//
// Classes
//
//*********************************************
wrap_table();
wrap_atom();
wrap_conformer();
wrap_bond();
wrap_stereogroup();
wrap_mol();
wrap_EditableMol();
wrap_ringinfo();
wrap_monomerinfo();
wrap_resmolsupplier();
wrap_molbundle();
//*********************************************
//
// Functions
//
//*********************************************
std::string docString;
python::def("tossit", tossit);
}