orthonym.assembly.handlers._handler_shared#
Note
Internal API. Names and behaviour may change between releases.
a phase shared handler helpers (DECOMP-01 + internal notes).
Substrate commit 02-00: lazy re-export wrappers around the canonical
implementations in composer.py. Per internal notes incremental-migration
discipline, composer.py STILL OWNS:
_name_iso_x_cyanate(composer.py:2204; 27 LOC) — shared between isocyanate (commit 02-04) and isothiocyanate (commit 02-05) handlers._name_r_group(composer.py:2233; 217 LOC) — shared between urea (commit 02-08), guanidine (commit 02-09), and the general_acyclic catch-all (Plan-03 commit 03-09).
The substrate ships THIS module so handler files can write the forward-looking import path:
from._handler_shared import name_iso_x_cyanate
from._handler_shared import name_r_group
while internally the symbols delegate (via lazy import inside each
function body) to composer.py. When Plan-03 commit 03-10 lands, the
function BODIES move here verbatim and composer.py’s
_name_iso_x_cyanate + _name_r_group definitions delete. The
re-export shape ensures handler files do NOT need to change import paths
at thinning time — only this delegation layer flips.
Per internal notes catch-all helper convention: shared logic between multiple handlers MUST live in this module (not duplicated across handlers/). The “≥ 2 handler” threshold is per internal notes + internal notes-DECOMP.md in-file-handler-body inventory.
Anti-pattern hygiene: - -02 banned: do NOT group two handlers into one extraction commit
because they share a body. The handlers are separate files; the SHARED helper lives HERE; each handler imports the helper but keeps its own file + own atomic commit.
-12 banned: handler logic in shim (must be 1-3-line wrapper). This module’s helpers ARE the multi-line logic; handlers import them.
References:
- composer.py:2204-2230 (_name_iso_x_cyanate) — verbatim source.
- composer.py:2233-2449 (_name_r_group) — verbatim source.
- internal notes § “Common Conventions” + line 458.
- 160-internal notes + — catch-all helper convention + migration.
PHASE 160.2 EXTENSION (Plan-02-01; internal notes +): Six NEW public functions lifted verbatim from composer.py per the two-step “helpers-first” extraction:
_generate_chain_parent (composer.py:3785-3818, 33 LOC)
_generate_ring_parent (composer.py:3821-3893, 72 LOC)
_generate_suffix (composer.py:3934-4076, 142 LOC)
_generate_prefixes (composer.py:4079-4282, 203 LOC)
_generate_stereodescriptors (composer.py:6634-6704, 70 LOC)
_assemble_fragments (composer.py:6799-6954, 155 LOC)
Each function body is COPIED VERBATIM from composer.py per a phase
mechanical-translation discipline. composer.py keeps thin re-export shims
(from.handlers._handler_shared import _generate_chain_parent at module
top) so all in-file call sites in _name_oxime_or_hydrazone,
_assemble_amide_name, _assemble_amine_name, _assemble_ring_with_ester_prefixes,
_assemble_complex_ring_name remain byte-identical per internal notes
forbidden-boundary preservation.
Per internal notes honest-fail-on-data: any byte-identical canary regression at commit 02-01 reverts the commit; remediation lands in a follow-up.
Module-level dependencies resolve via LAZY imports inside each function
body to avoid the circular dependency
_handler_shared.py -> composer.py -> _handler_shared.py that the
composer-side shim re-export creates at module-load time. composer.py
imports this module at its top; this module deferring composer.py imports
to first call breaks the cycle while preserving byte-identical behavior.
- orthonym.assembly.handlers._handler_shared.name_iso_x_cyanate(features, fg_key, suffix_word)#
Common implementation for isocyanate and isothiocyanate naming.
Lazy delegate to
composer.py:_name_iso_x_cyanate(composer.py:2204). Per internal notes + PATTERNS first-wave guidance, composer.py owns the canonical body at this commit; this wrapper provides the forward-looking import pathhandlers._handler_shared.name_iso_x_cyanatefor handler files that want stable paths now.SMARTS pattern:
[#6][NX2]=[CX2]=[OX1](isocyanate) or[#6][NX2]=[CX2]=[SX1](isothiocyanate). Match tuple:(R_carbon, N, C, O/S).- Parameters:
features (Any) – MolecularFeatures object.
fg_key (str) – Either
'isocyanate'or'isothiocyanate'.suffix_word (str) – The functional-class suffix word (
'isocyanate'/'isothiocyanate').
- Returns:
Functional class name like
'methyl isocyanate', or None.- Return type:
str | None
See also
composer.py:_name_iso_x_cyanate — canonical implementation. composer.py:_name_isocyanate / _name_isothiocyanate — single-line
callers; both move to handlers/{isocyanate,isothiocyanate}.py.
- orthonym.assembly.handlers._handler_shared.name_r_group(mol, start_idx, exclude_atoms)#
Name an R group (substituent fragment) starting from start_idx.
Lazy delegate to
composer.py:_name_r_group(composer.py:2233). Per internal notes + PATTERNS first-wave guidance.- Parameters:
mol (Any) – RDKit Mol object.
start_idx (int) – Atom index of the R-group attachment point.
exclude_atoms (set) – Set of atom indices to exclude from the R-group walk (e.g., the functional group atoms already named).
- Returns:
Substituent name as IUPAC substituent prefix (e.g.,
'methyl','phenyl','4-chlorophenyl'), or None on failure.- Return type:
str | None
See also
- composer.py:_name_r_group — canonical implementation; consumed by
urea, guanidine, isocyanate, isothiocyanate, and the general_acyclic catch-all.
- orthonym.assembly.handlers._handler_shared.cached_is_complex_ring_system(features)#
: per-features memoization of composer._is_complex_ring_system.
The SMARTS-based complex-ring check is heavy; predicates that call it inside the dispatch loop violate the spirit of internal notes (predicates are pure read-only over already-perceived state). Cache the result on the features object as a private attribute so partial_sat / polycyclic / ring_ester predicates share a single SMARTS evaluation per features instance instead of running it three times per dispatch.
The cache is per-features-instance state owned by features itself; the predicate remains pure with respect to shared/global state.
- Parameters:
features (Any) – MolecularFeatures-like object with a
molattribute.- Returns:
True iff the molecule is a complex ring system per the SMARTS check.
- Return type:
bool