diff --git a/corelib/src/libs/SireMol/molid.cpp b/corelib/src/libs/SireMol/molid.cpp index 6cb608d07..ddbb4bed4 100644 --- a/corelib/src/libs/SireMol/molid.cpp +++ b/corelib/src/libs/SireMol/molid.cpp @@ -266,6 +266,8 @@ QList MolIdx::map(const Molecules &molecules) const molnums.append(it.key()); break; } + + --i; } BOOST_ASSERT(not molnums.isEmpty()); diff --git a/corelib/src/libs/SireSearch/idengine.cpp b/corelib/src/libs/SireSearch/idengine.cpp index 73992526c..079f48830 100644 --- a/corelib/src/libs/SireSearch/idengine.cpp +++ b/corelib/src/libs/SireSearch/idengine.cpp @@ -31,8 +31,8 @@ #include "SireBase/booleanproperty.h" #include "SireBase/parallel.h" -#include "SireMol/atomelements.h" #include "SireMol/atomcoords.h" +#include "SireMol/atomelements.h" #include "SireMol/core.h" #include "SireMol/iswater.h" @@ -1155,9 +1155,63 @@ SelectResult IDIndexEngine::searchMolIdx(const SelectResult &mols, const SelectR { QList matches; - int idx = 0; int count = context.listCount(); + if (_is_single_value(this->vals)) + { + // For a single index value, apply Python-style negative-index mapping + // and do a strict bounds check. Out-of-bounds returns no match, + // consistent with residx/atomidx behaviour. + // We read the raw start value from RangeValue directly, bypassing the + // _to_single_value helper which maps against INT_MAX and corrupts + // negative indices. + auto rv = boost::get(this->vals[0]); + + if (not rv.start) + return SelectResult(matches); + + int v = *rv.start; + + if (v < 0) + v = count + v; + + if (v < 0 or v >= count) + return SelectResult(matches); + + int idx = 0; + + for (const auto &mol : context) + { + if (idx == v) + { + if (&mols == &context) + { + matches.append(mol->molecule()); + } + else + { + const auto molnum = mol->data().number(); + + for (const auto &m : mols) + { + if (m->data().number() == molnum) + { + matches.append(m->molecule()); + break; + } + } + } + break; + } + + idx += 1; + } + + return SelectResult(matches); + } + + int idx = 0; + for (const auto &mol : context) { if (this->match(idx, count)) diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst index 85ccdef5f..48b41ddfa 100644 --- a/doc/source/changelog.rst +++ b/doc/source/changelog.rst @@ -40,6 +40,10 @@ organisation on `GitHub `__. * Map the end-state ``element`` property when performing hydrogen mass repartitioning on perturbable molecules. +* Fixed out-of-bounds ``molidx`` searches silently returning the last molecule instead of + raising a ``KeyError``. Out-of-bounds positive and negative single-index values now + behave consistently with ``residx`` and ``atomidx``. + `2025.4.0 `__ - February 2026 ---------------------------------------------------------------------------------------------