orthonym.data.sugar_names#

Note

Internal API. Names and behaviour may change between releases.

Sugar retained names lookup table and glycosyloxy prefix formatting.

Provides canonical SMILES -> (anomer, config, base_name) mapping for common sugars, plus conversion to IUPAC glycosyloxy prefix format.

All canonical SMILES were generated by OPSIN 2.8.0 name->SMILES conversion then RDKit canonicalization. Verified for all 44 common sugar forms plus 12 modified sugars (N-acetyl, glucuronic acid).

OPSIN carbohydrate data integrated in a phase Plan 03: - 13 simpleGroup entries (meglumine, glucamine, sorbitol, etc.) - 22 ring entries (ascorbic acid, garosamine, neuraminic acid, etc.) - 23 carbohydrate suffix rules (reference lookup for future use)

Usage:

from orthonym.data.sugar_names import lookup_sugar, sugar_to_glycosyloxy_prefix

info = lookup_sugar(“OC[C@H]1O[C@@H](O)[C@H](O)[C@@H](O)[C@@H]1O”) # -> (“beta”, “D”, “glucopyranose”)

prefix = sugar_to_glycosyloxy_prefix(“beta”, “D”, “glucopyranose”) # -> “β-D-glucopyranosyloxy”

orthonym.data.sugar_names.lookup_sugar(canonical_smiles)#

Look up a sugar retained name by canonical SMILES.

First tries exact match (stereo-specific). If no match and the SMILES has no @ characters, falls back to connectivity-only matching — but only for a skeleton that exactly one configurational base name occupies.

⚠ The connectivity-only fallback is NOT a general “drop the descriptors you cannot determine” rule, and treating it as one was a real defect (PF). The sugar base name is itself configurational: all 8 hexopyranoses share the single skeleton OCC1OC(O)C(O)C(O)C1O, so answering glucopyranose for it picks one of 8 by dictionary order. Ambiguous skeletons now return None and the systematic namer handles them. See _build_nonstereo_fallback.

Parameters:

canonical_smiles (str) – RDKit canonical SMILES of the sugar fragment.

Returns:

Tuple of (anomer, config, base_name) or None if not a known sugar. For non-stereo matches, anomer and config are empty strings.

Return type:

Tuple[str, str, str] | None

Examples

>>> lookup_sugar("OC[C@H]1O[C@@H](O)[C@H](O)[C@@H](O)[C@@H]1O")
('beta', 'D', 'glucopyranose')
>>> lookup_sugar("OCC1OC(O)C(O)C(O)C1O") # non-stereo hexopyranose
None
>>> lookup_sugar("CCCC")
None
orthonym.data.sugar_names.sugar_to_glycosyloxy_prefix(anomer, config, base_name)#

Convert sugar info to glycosyloxy prefix string.

Transforms the base sugar name ending from “-ose” to “-osyloxy” and prepends anomer-config descriptors if present.

Parameters:
  • anomer (str) – Anomeric descriptor (“alpha”, “beta”, or “”).

  • config (str) – Configurational descriptor (“D”, “L”, or “”).

  • base_name (str) – Sugar base name (e.g., “glucopyranose”).

Returns:

Glycosyloxy prefix string.

Return type:

str

Examples

>>> sugar_to_glycosyloxy_prefix("beta", "D", "glucopyranose")
'β-D-glucopyranosyloxy'
>>> sugar_to_glycosyloxy_prefix("alpha", "L", "rhamnopyranose")
'α-L-rhamnopyranosyloxy'
>>> sugar_to_glycosyloxy_prefix("", "", "glucopyranose")
'glucopyranosyloxy'
orthonym.data.sugar_names.glycosyl_substituent_prefix(mol, frag_atoms, attach_idx)#

Name an O-linked cyclic monosaccharide substituent, or None.

Blue Book ** “O-Glycosyl compounds”** (the Blue Book Blue Book):

“The substituent group formed by removal of a hydrogen atom from the anomeric -OH group is considered as a compound substituent group formed by the ‘glycosyl’ group and an ‘oxy’ group. In the examples, names are formed by using the seniority of class to determine the principal characteristic group to be assigned to the monosaccharide or to the aglycone component.”

Its worked example (:53927) fixes every open question:

1-[4-(β-D-glucopyranosyloxy)phenyl]ethan-1-one
  [not 4'-(β-D-glucopyranosyloxy)acetophenone...]
  (not 4-acetylphenyl β-D-glucopyranoside;
   a ketone is senior to a hydroxy compound)

The glycosyloxy group is a detachable prefix on the aglycone parent, so it is cited at the aglycone’s attachment locant (4-) inside enclosing marks, and the glycosylated oxygen appears only inside that prefix – the parent must not also cite it as a hydroxy. Per **** (:53896) “No locant is added to the name of the substituent to indicate the position of the free valence”, so the glycosyl token itself carries no internal locant.

Returning the prefix lets the ordinary parent+prefix machinery assign that locant and cite the remaining hydroxy groups, which is what makes the oxygen single-counted. This function therefore does perception only; it never builds a whole-molecule name.

Deliberately fails closed (returns None, so the cascade falls through) for every shape whose PIN morphology is a different construction:

  • a substituted glycosyl – ‘s third example (:53935) spells it 5-{[4,6-dideoxy-4-(dimethylamino)-α-D-glucopyranosyl]oxy}, i.e. the decorated glycosyl goes inside its own enclosing marks before ‘oxy’. sugar_to_glycosyloxy_prefix cannot build that, so a base name carrying any locant or decoration is refused rather than mis-spelled.

  • a uronic glycosyl – ‘s second example (:53929) cites it as β-D-glucopyranosyluronic acid, not as a ‘…osyloxy’ token. The naive contraction ‘glucuronopyranosyloxy’ is a fabricated morpheme (measured: OPSIN cannot parse it), so it is refused here.

  • an anomer/configuration-less sugar – sugar_to_glycosyloxy_prefix drops both descriptors together when either is absent, which would spell a stereochemically unspecified group for a molecule that has a definite anomeric configuration.

Parameters:
  • mol – RDKit Mol of the whole molecule.

  • frag_atoms – Atom indices of the substituent fragment – the glycosidic oxygen together with the entire glycosyl group.

  • attach_idx – Index within frag_atoms of the atom bonded to the parent, i.e. the glycosidic oxygen.

Returns:

The <glycosyl>oxy compound prefix (e.g. β-D-glucopyranosyloxy), or None to fall through to the remaining tiers.

Return type:

str | None

orthonym.data.sugar_names.sugar_to_glycoside_class_name(anomer, config, base_name)#

Convert sugar info to a functional-class glycoside head word.

Transforms the base sugar name ending from -ose to -oside (so glucopyranose -> glucopyranoside, fructofuranose -> fructofuranoside) and prepends the ASCII anomer-config- descriptor cluster when both are present /).

The descriptors stay ASCII (β-D-), never Greek β — the gold harness normalize does not transliterate (Pitfall 6).

Parameters:
  • anomer (str | None) – Anomeric descriptor (“alpha”, “beta”, or “”).

  • config (str | None) – Configurational descriptor (“D”, “L”, or “”).

  • base_name (str) – Sugar base name (e.g., “glucopyranose”).

Returns:

The glycoside head word, e.g. “β-D-glucopyranoside”.

Return type:

str

Examples

>>> sugar_to_glycoside_class_name("beta", "D", "glucopyranose")
'β-D-glucopyranoside'
>>> sugar_to_glycoside_class_name("alpha", "L", "rhamnopyranose")
'α-L-rhamnopyranoside'
>>> sugar_to_glycoside_class_name("", "", "glucopyranose")
'glucopyranoside'
orthonym.data.sugar_names.uronic_glycoside_head(anomer, config, base_name)#

Convert a uronic-acid sugar tuple to its functional-class glycoside head.

The catalog base for a uronic acid is glucuronopyranose (URONIC_ACID_NAMES :137); but the IUPAC glycoside head form is NOT glucuronopyranoside — it is glucopyranosiduronic acid (the -ose -> -oside swap applies to the parent hexose stem, and the C6-carboxyl becomes the -uronic acid suffix). sugar_to_glycoside_class_name would wrongly emit glucuronopyranoside.

Implemented as an explicit map (NOT string surgery — avoids gluc -> gluco edge cases). β-D-glucopyranosiduronic acid is OPSIN-RT verified (a phase, against CHEBI:133504/133517). Galacto is forward-looking (Assumption A1: no corpus row, RT unverified) — kept in the map but carries no gold dependency.

Blue Book : “change ‘pyran’ to ‘pyranoside’, elide final ‘e’, giving ‘pyranosiduronic acid’.” Example: methyl β-D-glucopyranosiduronic acid.

Parameters:
  • anomer (str | None) – Anomeric descriptor (“alpha”, “beta”, or “”).

  • config (str | None) – Configurational descriptor (“D”, “L”, or “”).

  • base_name (str) – Uronic sugar base (e.g. “glucuronopyranose”).

Returns:

The uronic glycoside head, e.g. “β-D-glucopyranosiduronic acid”; None for a non-uronic / unknown base.

Return type:

str | None

Examples

>>> uronic_glycoside_head("beta", "D", "glucuronopyranose")
'β-D-glucopyranosiduronic acid'
>>> uronic_glycoside_head("alpha", "D", "xyz") is None
True
orthonym.data.sugar_names.uronic_free_acid_name(anomer, config, base_name)#

Convert a uronic-acid sugar tuple to its FREE-acid (non-glycoside) name.

The catalog base for a uronic acid is glucuronopyranose (URONIC_ACID_NAMES:137); but that string is OPSIN-UNPARSEABLE — emitting it as a free name yields unknown organic compound . The correct IUPAC free-acid form is glucopyranuronic acid: the parent hexose stem keeps its -pyranose ring designator, the final -e is elided, and the C6-carboxyl is named with the -uronic acid suffix (glucopyranose -> glucopyran + uronic acid = glucopyranuronic acid).

This is the FREE-acid sibling of:func:uronic_glycoside_head (which emits the -osiduronic acid glycoside head). Both are implemented as explicit maps (NOT string surgery — the contributor guide root-cause; avoids the gluc -> gluco edge cases). URONIC_ACID_NAMES keeps its base value glucuronopyranose UNCHANGED so uronic_glycoside_head’s UREONIC_HEAD key still matches (Pitfall 5 coupling — must not regress the Phase-182 glucuronide glycoside).

β-D-glucopyranuronic acid is OPSIN-RT True (verified this session). Galacto is forward-looking (Assumption A1: no corpus/gold row, RT unverified) — kept in the map but carries no gold dependency.

Blue Book : a monosaccharide whose terminal -CH2OH is oxidized to -COOH is named by changing the -ose of the parent name to -uronic acid.

Parameters:
  • anomer (str | None) – Anomeric descriptor (“alpha”, “beta”, or “”).

  • config (str | None) – Configurational descriptor (“D”, “L”, or “”).

  • base_name (str) – Uronic sugar base (e.g. “glucuronopyranose”).

Returns:

The free uronic-acid name, e.g. “β-D-glucopyranuronic acid”; None for a non-uronic / unknown base (fail-closed,).

Return type:

str | None

Examples

>>> uronic_free_acid_name("beta", "D", "glucuronopyranose")
'β-D-glucopyranuronic acid'
>>> uronic_free_acid_name("alpha", "D", "galacturonopyranose")
'α-D-galactopyranuronic acid'
>>> uronic_free_acid_name("a", "b", "zzz") is None
True
orthonym.data.sugar_names.recognize_sugar_skeleton(mol, anomeric_idx=None)#

Derive (anomer, config, base) from a sugar’s structure.

Generalizes the exact-stereo lookup_sugar catalog: it maps the molecule’s canonical ring-stereocenter CIP fingerprint to the catalog (anomer, config, base) tuple. Hard-gated to reproduce every structurally-clean stereo catalog entry; returns None (never a wrong tuple) on any deviation from the clean hexose/pentose OH/H/CH2OH fingerprint — deoxy / amino / N-acetyl / uronic / C-modified / non-6-ring sugars defer to the catalog or a phase (, fail-closed).

Parameters:
  • mol – RDKit Mol of the free-sugar fragment (anomeric -OH present).

  • anomeric_idx (int | None) – Optional anomeric carbon index. When None (the robust default), the deriver self-locates the anomeric carbon inside the fragment (ring C bonded to ring O AND an exocyclic O).

Returns:

(anomer, config, base_name) identical in shape to lookup_sugar, or None on out-of-scope / ambiguous input.

Return type:

Tuple[str, str, str] | None

orthonym.data.sugar_names.name_monosaccharide_systematic(mol, for_glycosidic_unit=False)#

Systematic name for a non-cataloged deoxy/amino/uronic sugar ring.

A sibling GENERALIZATION of:func:recognize_sugar_skeleton : for a single 5/6-membered sugar ring that the clean-ring deriver fails closed on (because it carries a deoxy / amino / uronic modification), this engine

  1. reuses the analog’s gates (single ring; one ring-O; one anomeric C via _locate_anomeric_carbon()) and derives the ring size -> pyranose (6) / furanose (5);

  2. classifies the modified positions STRUCTURALLY with IUPAC-derived locants (_classify_sugar_positions(),);

  3. PHYSICALLY idealizes the ring to its parent aldose skeleton (_idealize_to_parent(), the three RESEARCH edits), re-runs rdCIPLabeler.AssignCIPLabels, and recovers (anomer, config, base) from the gate-proven:data:_SKELETON_FINGERPRINT_INDEX (Pitfall 1 — the raw modified fingerprint does NOT equal the clean parent);

  4. assembles the name :

    • URONIC: map the idealized clean base to the uronic-tagged base via the explicit:data:_URONIC_STEM_MAP (Warning 2 — NEVER inline str.replace/re.sub), then emit uronic_free_acid_name() -> β-D-glucopyranuronic acid;

    • DEOXY / AMINO /: emit alphabetized detachable prefixes with their derived locants -> {prefixes}-{anomer}-{config}-{base} (e.g. 6-deoxy-β-D- glucopyranose, 3-amino-3-deoxy-β-D-glucopyranose); amino alphabetizes before deoxy.

Fail-closed : returns None for a non-sugar, a clean cataloged ring (that is lookup_sugar’s job,), a C-glycoside / anhydro ring (no clean idealized fingerprint), an out-of-map uronic skeleton, or a C7+ cyclic sugar (no:data:_SKELETON_FINGERPRINT_INDEX entry, Assumption A3) — so the existing pipeline stays byte-identical. Descriptors are ASCII (β-D-, Pitfall 6). The input mol is never mutated.

Parameters:
  • mol – RDKit Mol of a free monosaccharide (anomeric -OH present).

  • for_glycosidic_unit (bool) – .2 – when True (only the oligosaccharide unit-recognizer, rules.oligosaccharides._recognize_unit, passes this), (a) an O-acyl / N-acyl ring decoration (o_acyl / n_acyl in _classify_sugar_positions()’s output) is THREADED into the name as a substituent prefix instead of forcing an early None – that decoration is a genuine chain-donor/-acceptor shape (e.g. a heparin-style O-acetylated or non-catalog-N-acyl residue mid-chain), not a standalone free sugar, so there is no “defer to the retained functional-class ester name” option to fall back on; (b) the O-sulfo/O-phospho “defer to name_sugar_ester’s catalog-residual functional-class form” check below is skipped for the same reason – the PREFIX form (6-O-sulfo-...) is the only one composable as a glycosyl unit. Default False keeps EVERY existing caller (the free- sugar path, name_sugar_ester’s own residual recursion, etc.) byte-identical: an O-acyl/N-acyl-decorated ring still returns None exactly as it did before this parameter existed (single-residue free-sugar O-acyl/N-acyl support is a separate, later lever).

Returns:

The systematic name, or None when out of scope.

Return type:

str | None

Examples

>>> from rdkit import Chem
>>> m = Chem.MolFromSmiles("C[C@H]1O[C@@H](O)[C@H](O)[C@@H](O)[C@@H]1O")
>>> name_monosaccharide_systematic(m)
'6-deoxy-β-D-glucopyranose'
orthonym.data.sugar_names.name_free_sugar(mol, canonical_smiles)#

Name a free (non-glycosidic) monosaccharide: catalog-join then systematic.

This is the exact catalog-join + systematic cascade the carbohydrate dispatch handler used inline (routing/dispatch_table._handle_carbohydrate_lookup); factored here so the free-sugar-ester path (name_sugar_ester()) can name the residual sugar through the SAME code (DRY, no drift). Returns the sugar name or None (a catalog uronic-base whose:func:uronic_free_acid_name fails, or an out-of-scope ring). Byte-identical to the handler’s prior logic.

orthonym.data.sugar_names.name_sugar_ester(mol, canonical_smiles)#

Free-sugar mono-phosphate / sulfate ester (BB /.

The sugar is the parent; the ester is cited after the sugar name with its locant: D-glucopyranose 6-(dihydrogen phosphate) (BB 53209), α-D-glucopyranose 2-sulfate (ionized) / 2-(hydrogen sulfate) (acid, BB 53231), α-D-glucopyranose 1-phosphate (ionized glycosyl phosphate) / 1-(dihydrogen phosphate) (acid, BB 53213). The protonation-state word is derived IN PLACE from the acid centre (never neutralize-then-rename), reusing the class-agnostic conjugate_controller primitives.

Multi-ester (W6B-T3, BB: 2-3 mono-phosphate esters of one sugar -> D-fructofuranose 1,6-bis(dihydrogen phosphate) (bis/tris, the

complex multiplier since the ester word carries a space).

Fail-closed (accuracy-first) on: >3 esters, a di/tri-phosphate or P-O-P bridge (183/184 territory), mixed protonation states, any non-sugar-ring molecule, or a residual the free-sugar namer cannot name. Every emitted name is OPSIN-round-trip gated (_mono_name_rt_ok()) so a wrong locant/anomer cascade-continues rather than shipping. The input mol is never mutated.

orthonym.data.sugar_names.name_free_sugar_decorated_prefix(mol)#

.4: standalone free sugar bearing N-acyl (amide) decoration, or O-acyl COMBINED with N-acyl on the same ring – the two shapes name_free_sugar() (default for_glycosidic_unit=False) and name_sugar_ester()’s functional-class ester route cannot express:

  • there is no BB functional-class analog for an amide (an N-acyl amino sugar is cited by its acetamido-style PREFIX even standalone, e.g. the catalog’s own 2-acetamido-2-deoxy-glucopyranose), so a NON-catalog N-acyl (e.g. N-propanoyl) has nowhere else to go;

*name_sugar_ester()’s O-acyl strip-and-recurse

(_name_sugar_acyl_ester()) names its residual via name_free_sugar(), which hits the SAME for_glycosidic_unit=False fence on any N-acyl left in that residual – so an O-acyl+N-acyl ring declines even though the O-acyl alone would have named fine.

Reuses the IDENTICAL prefix-embedding engine.2 proved correct for the oligosaccharide glycosidic-unit path (name_monosaccharide_systematic(mol, for_glycosidic_unit=True), BB

/ – for a STANDALONE ring that assembled string

IS already the complete systematic name; no glycosidic wrapping needed.

Tried ONLY after:func:name_free_sugar and:func:name_sugar_ester have both declined (dispatch order in routing.dispatch_table._handle_carbohydrate_lookup), so it never preempts the preferred functional-class spelling (β-D-glucopyranose 6-acetate) for the uniform-single-word, N-acyl-free O-acyl case that route already names correctly.

Fail-closed / RT-gated:name_monosaccharide_systematic()’s own OPSIN round-trip backstop (_mono_name_rt_ok()) already guards this path, so a candidate that does not verify never ships (returns None -> the existing pipeline cascade-continues).

orthonym.data.sugar_names.name_aldonate_ester(mol, canonical_smiles)#

Open-chain ALDONATE ester (BB: the C1-COOH of an open-chain aldonic acid is esterified -> <R> <config>-<stem>onate (propan-2-yl D-gluconate).

Strip-and-name: the alkyl (R) group is named via the ester machinery (get_alkyl_fragment_name()); the residual free sugar-acid must be a RECOGNIZED aldonic acid (name_free_sugar()), else fail-closed. OPSIN-RT gated; input mol never mutated.

The aldarate PARTIAL ester is DEFERRED fail-closed: the residual free diacid canonicalizes identically regardless of which terminus bore the ester, so the esterified-terminus locant/config cannot be derived without shipping a wrong name for the opposite-terminus isomer.

orthonym.data.sugar_names.name_glycosyloxy_yl_parent(mol, canonical_smiles)#

Glycosyloxy n-O-yl substituent on a senior parent (BB.

A monosaccharide bonded through a non-anomeric ring-position oxygen to a senior parent (e.g. acetic acid) is cited as the substituent <anomer>-<config>-glycopyranos-<n>-O-yl (the locant distinguishes it from the C-1 glycosyl); the parent bears the principal characteristic group and is named normally -> (β-D-glucopyranos-2-O-yl)acetic acid.

Deterministic + fail-closed: recognise a single clean sugar ring + a non-anomeric exocyclic ether O to a non-ring parent carbon; reconstruct the free sugar (ether O -> OH) via lookup_sugar/recognize_sugar_skeleton; name the parent fragment via a gate-off inner namer; then pick the n-O-yl LOCANT by a HARD OPSIN round-trip of each candidate against the input (opsin_parse fails-CLOSED without Java). Any miss -> None (cascade-continue). Never mutates the input mol.

orthonym.data.sugar_names.name_c_substituted_sugar(mol, canonical_smiles)#

Memoising front of:func:_name_c_substituted_sugar_impl (Lever M, 2026-09-12).

The impl enumerates every stereoisomer of the reconstructed parent and OPSIN-checks each candidate name; on the 60 slowest molecules of a 7,000-row sample it ran 321 times and enumerated 61,083 isomers (15 % of that time). Its result depends only on the input structure, so within one naming scope the same molecule (canonical isomeric SMILES) is named once. Outside a scope, or when the key cannot be built, the impl runs directly.

orthonym.data.sugar_names.name_amino_deoxy_open_sugar(mol, canonical_smiles)#

N-alkylamino open-chain aldose (BB: a backbone carbon of an open-chain aldose bears -N(H)R (R = alkyl) in place of -OH -> <n>-(<R>amino)-<n>-deoxy-<config>-<stem> (2-(butylamino)-2-deoxy-D-glucose).

Strip-and-name: replace the N (and its R group) with -OH IN PLACE (preserving the backbone stereo tag), name the parent aldose via:func:name_free_sugar, and cite the N-substituent. OPSIN-RT gated. Fail-closed on a ring form, N-acyl / N-hydroxyalkyl (R carries O), or more than one amino carbon.

orthonym.data.sugar_names.name_glycosyloxy_aglycone(mol, canonical_smiles)#

Glycosyloxy on a senior aglycone (BB: a sugar O-glycosidically bonded to an aglycone that bears a characteristic group SENIOR to hydroxy is named as a (<config>-glycosyloxy) substituent PREFIX on the aglycone parent (1-[4-(β-D-glucopyranosyloxy)phenyl]ethan-1-one).

Placeholder mechanism (root-cause, RT-gated): replace the sugar with a methyl (-> the aglycone methyl ether, which Orthonym names natively), require the aglycone to carry a senior-group suffix (else it is a simple glycoside -> fail-closed for the glycoside path), then swap the single methoxy token for (<glycosyloxy>) and escalate its enclosing marks nesting ORDER (BB 7444; escalation, BB 7509) under the marks requirement (BB 7232)). Fail-closed on >1 sugar ring, a free/undefined anomeric, a non-senior aglycone, or an RT-fail.

orthonym.data.sugar_names.sugar_to_glycosyl_prefix(anomer, config, base_name)#

Convert sugar info to a C-glycosyl substituent prefix (-ose -> -osyl, NO oxy): sugar_to_glycosyl_prefix("beta","D","glucopyranose") -> 'β-D-glucopyranosyl'.

orthonym.data.sugar_names.name_c_glycosyl_aglycone(mol, canonical_smiles)#

C-glycosyl on a senior aglycone (BB: a sugar bonded by a C-C bond from its anomeric carbon to an aglycone that is the parent -> n-(<config>-glycosyl) substituent prefix (2-(β-D-glucopyranosyl)benzene-1,3,5-triol).

Placeholder mechanism (RT-gated): cap the anomeric-C — aglycone-C bond to recognize the sugar, then replace the sugar with a methyl (-> the aglycone methyl-substituted parent, named natively), and swap the single methyl token for (<glycosyl>). Fail-closed on >1 sugar ring, an exocyclic-O anomeric (that is an O-glycoside, T12), an unrecognized sugar, or an RT-fail.

orthonym.data.sugar_names.name_sugar_o_methyl(mol, canonical_smiles)#

O-methyl ether sugar (BB: non-anomeric ring/exocyclic C-OH methylated -> <locants>-<mult>-O-methyl-<sugar> (e.g. 2,3,4,6-tetra-O-methyl-β-D-glucopyranose, 2-O-methyl-α-L- rhamnopyranose).

Strip-and-name (safe against sugar-ring-oxygen-drop): every -O-CH3 is stripped to -OH, the residual must be a RECOGNIZED free sugar (name_free_sugar), else fail-closed (a non-sugar oxane’s residual is not recognized). An -O-CH3 at the ANOMERIC position is a glycoside (methyl glycopyranoside), NOT an O-methyl ether -> fail-closed so the glycoside path handles it. Only bare -O-CH3 is in scope (O-acyl / O-alkyl-larger / mixed-ester -> fail-closed). OPSIN-RT gated; input mol never mutated.

orthonym.data.sugar_names.name_glycosylamine(mol, canonical_smiles)#

Glycosylamine (BB /: anomeric -OH replaced by a bare -NH2, named <anomer>-<config>-glyco...osylamine (e.g. β-D-glucopyranosylamine). Bare primary amine only (N-substituted -> fail-closed). Every emitted name OPSIN-RT gated. Input mol never mutated.

orthonym.data.sugar_names.name_glycosyl_halide(mol, canonical_smiles)#

Glycosyl halide (BB: anomeric -OH replaced by a single halogen, named by the functional-class two-word form <anomer>-<config>-glyco...osyl <halide> (e.g. α-D-glucopyranosyl bromide). Mono-halo at the anomeric only; fail-closed otherwise. OPSIN-RT gated. Input mol never mutated.