Skip to content

Add element_names: per-element semantic labels on ports (slice 1: core) - #3624

Open
jonhanke-nam wants to merge 5 commits into
develfrom
jonhanke-dev-branches/element-names-core
Open

Add element_names: per-element semantic labels on ports (slice 1: core)#3624
jonhanke-nam wants to merge 5 commits into
develfrom
jonhanke-dev-branches/element-names-core

Conversation

@jonhanke-nam

Copy link
Copy Markdown
Collaborator

Adds an optional, purely-additive element_names label list to InputPort/OutputPort (with a Mechanism-level shorthand): one semantic label per element of a port's value vector. Opt-in, None by default, and does not participate in execution. 5 files, +107 on devel.

# per-port
m = pnl.TransferMechanism(default_variable=[[0, 0]],
    input_ports=[pnl.InputPort(name='SRC', element_names=['red_word', 'green_word'])])

# Mechanism shorthand (applies to default input + output port,
# only when those ports don't already carry their own labels)
m = pnl.TransferMechanism(input_shapes=2, element_names=['red_word', 'green_word'])

Motivation: downstream inspection/introspection tools want to show what each element of a node's value means (e.g. which unit is "red" vs "green") instead of a numeric index. This has been stabilized against a real consumer (the PsyNeuView model viewer), which reads the labels via the _debugger NODE_EXECUTION snapshot. Kept deliberately small and additive; this is the first of a few focused slices (see design discussion below).

Design
  • Stored as a static, read-only structural ParameterParameter(None, stateful=False, loggable=False, read_only=True, structural=True) — mirroring InputPort.default_input / shadow_inputs. Chosen (over a plain attribute) to match how PsyNeuLink already carries construction-time port metadata, so it flows through the Parameters machinery uniformly.
  • The Mechanism shorthand applies the list to the default (first) input port and default output port, but only when those ports don't already carry their own element_names (per-port labels always win). It sets the read-only Parameter via parameters.element_names.set(..., override=True).
  • Length is validated against the port's value size at construction; a mismatch raises PortError.
Scope & behavior
  • Distinct from input_labels / output_labels (those map symbolic names → whole value vectors; this maps element index → label).
  • element_names is populated once the port is instantiated into a Mechanism — exactly like default_input and every other port Parameter (a standalone/deferred port raises ParameterNoValueError for it, same as the others). This is the one intentional behavior refinement vs. an eager-attribute approach; called out so it's not a surprise.
  • Excluded from LLVM compilation via the _get_compilation_params blacklist, alongside the other non-computational structural params (default_input, shadow_inputs, internal_only).
Backward compatibility
  • Purely additive: default None, no execution participation. If this perturbed execution or component structure, the existing test matrix would fail — it passes unchanged locally (ports incl. LLVMRun, test_parameters, and the MDF round-trip suite all green).
  • Adding the Parameter initially tripped the LLVM "unused parameter" assertion; resolved by blacklisting element_names from compilation like the sibling structural params. No other changes to compiled structures.
Tests

tests/misc/test_element_names.py — 11 tests: additive default (None), per-port labels, the Mechanism shorthand, per-port override of the shorthand, list-copy semantics, falsy-as-unset, and length-mismatch PortError. Ports are exercised as owned (inside a Mechanism).

Files changed
  • ports/inputport.py, ports/outputport.py — the element_names Parameter + constructor arg
  • ports/port.py — length validation helper + call site in Port_Base.__init__
  • mechanisms/mechanism.py — the Mechanism-level shorthand
  • components/component.py — LLVM compilation blacklist entry
  • tests/misc/test_element_names.py — the tests

Design discussion and the remaining slices (propagation, MDF round-trip, debugger surface) are tracked here: jonhanke-nam/PsyNeuLink#23. This is the first focused submission alongside the jonhanke-dev feature preview (#3558). Opening as a draft for a first look before review.

jonhanke-nam and others added 2 commits August 18, 2026 14:23
…hand

Add an optional `element_names` label list to InputPort/OutputPort and a
Mechanism-level shorthand that applies to the default input+output ports.
Stored as a static, read-only structural Parameter (stateful=False,
loggable=False, read_only=True, structural=True), mirroring InputPort's
existing default_input/shadow_inputs. Length is validated against the port's
value size at construction (PortError on mismatch). Excluded from LLVM
compilation via the _get_compilation_params blacklist, alongside the other
non-computational structural params (default_input, shadow_inputs).

Purely additive: element_names defaults to None and does not participate in
execution. Distinct from input_labels/output_labels (symbolic-name ->
value-vector maps).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
11 tests covering the additive default (None), per-port labels, the
Mechanism shorthand, per-port override of the shorthand, list-copy
semantics, falsy-as-unset, and length-mismatch PortError. Ports are
exercised as owned (inside a Mechanism), consistent with how every other
port Parameter is populated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment on lines +1812 to +1814
from psyneulink.core.components.ports.port import (
_validate_element_names_length,
)
@coveralls

coveralls commented Aug 18, 2026

Copy link
Copy Markdown

Coverage Status

coverage: 84.21% (+0.002%) from 84.208% — jonhanke-dev-branches/element-names-core into devel

@github-actions

Copy link
Copy Markdown

This PR causes the following changes to the html docs (ubuntu-latest-3.11):

diff -r docs-base/InputPort.html docs-head/InputPort.html
686c686
< <em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.components.ports.inputport.</span></span><span class="sig-name descname"><span class="pre">InputPort</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">owner</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">reference_value</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">variable</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">input_shapes</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">default_input</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">function</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">projections</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">combine</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">weight</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">exponent</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">internal_only</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">params</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">name</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">prefs</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">context</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.ports.inputport.InputPort" title="Link to this definition">¶</a></dt>
---
> <em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.components.ports.inputport.</span></span><span class="sig-name descname"><span class="pre">InputPort</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">owner</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">reference_value</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">variable</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">input_shapes</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">default_input</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">function</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">projections</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">combine</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">weight</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">exponent</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">internal_only</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">params</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">name</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">prefs</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">context</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">element_names</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.ports.inputport.InputPort" title="Link to this definition">¶</a></dt>
719a720,726
> <li><p><strong>element_names</strong> (<em>list</em><em> of </em><em>str : default None</em>) – optional semantic labels for each element of the InputPort’s
> <a class="reference internal" href="#psyneulink.core.components.ports.inputport.InputPort.value" title="psyneulink.core.components.ports.inputport.InputPort.value"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">value</span></code></a>, surfaced by the <code class="xref any docutils literal notranslate"><span class="pre">_debugger</span></code>
> NODE_EXECUTION snapshot and consumed by inspection tools. The
> list length must equal the size of the port’s value; a mismatch
> raises a <a class="reference internal" href="Port.html#psyneulink.core.components.ports.port.PortError" title="psyneulink.core.components.ports.port.PortError"><code class="xref any py py-exc docutils literal notranslate"><span class="pre">PortError</span></code></a> at construction. Stored as a static,
> read-only structural <a class="reference internal" href="Parameters.html#psyneulink.core.globals.parameters.Parameter" title="psyneulink.core.globals.parameters.Parameter"><code class="xref any py py-class docutils literal notranslate"><span class="pre">Parameter</span></code></a> that does not participate in
> execution.</p></li>
880a888,899
> <dt class="sig sig-object py" id="psyneulink.core.components.ports.inputport.InputPort.element_names">
> <span class="sig-name descname"><span class="pre">element_names</span></span><a class="headerlink" href="#psyneulink.core.components.ports.inputport.InputPort.element_names" title="Link to this definition">¶</a></dt>
> <dd><p>the value passed to the <strong>element_names</strong> argument of the constructor (or <code class="docutils literal notranslate"><span class="pre">None</span></code> if unset). See the
> argument description for usage and validation rules.</p>
> <dl class="field-list simple">
> <dt class="field-odd">Type<span class="colon">:</span></dt>
> <dd class="field-odd"><p>list of str or None</p>
> </dd>
> </dl>
> </dd></dl>
> 
> <dl class="py attribute">
1107a1127
> <li><a class="reference internal" href="#psyneulink.core.components.ports.inputport.InputPort.element_names"><code class="docutils literal notranslate"><span class="pre">InputPort.element_names</span></code></a></li>
diff -r docs-base/Mechanism.html docs-head/Mechanism.html
1058a1059,1068
> <li><p><strong>element_names</strong> (<em>list</em><em> of </em><em>str : default None</em>) – Mechanism-level shorthand that assigns semantic labels to each
> element of the Mechanism’s default (primary) <a class="reference internal" href="InputPort.html"><span class="doc">InputPort</span></a> <em>and</em>
> default <a class="reference internal" href="OutputPort.html"><span class="doc">OutputPort</span></a>, but only when those ports don’t already
> carry their own <code class="docutils literal notranslate"><span class="pre">element_names</span></code>. Equivalent to passing
> <code class="docutils literal notranslate"><span class="pre">element_names=[...]</span></code> to both ports individually; per-port
> labels always win if both are supplied. Distinct from
> <strong>input_labels</strong> / <strong>output_labels</strong>, which map symbolic names
> to value vectors. The list length must equal the size of the
> default port’s value; a mismatch raises a <a class="reference internal" href="Port.html#psyneulink.core.components.ports.port.PortError" title="psyneulink.core.components.ports.port.PortError"><code class="xref any py py-exc docutils literal notranslate"><span class="pre">PortError</span></code></a> at
> construction.</p></li>
diff -r docs-base/OutputPort.html docs-head/OutputPort.html
651c651
< <em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.components.ports.outputport.</span></span><span class="sig-name descname"><span class="pre">OutputPort</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">owner</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">reference_value</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">variable</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">input_shapes</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">function</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">projections</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">params</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">name</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">prefs</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">index</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">assign</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.ports.outputport.OutputPort" title="Link to this definition">¶</a></dt>
---
> <em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.components.ports.outputport.</span></span><span class="sig-name descname"><span class="pre">OutputPort</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">owner</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">reference_value</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">variable</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">input_shapes</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">function</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">projections</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">params</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">name</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">prefs</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">index</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre
...

See CI logs for the full diff.

…erialization

The Mechanism shorthand set only the override value, so shorthand-labeled
ports read back correctly via port.element_names but serialized as None to MDF
(which reads the parameter default). Set both the default and the override so
the shorthand behaves identically to an explicit per-port element_names
everywhere -- reads, MDF export, and future round-trip.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

This PR causes the following changes to the html docs (ubuntu-latest-3.11):

diff -r docs-base/InputPort.html docs-head/InputPort.html
686c686
< <em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.components.ports.inputport.</span></span><span class="sig-name descname"><span class="pre">InputPort</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">owner</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">reference_value</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">variable</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">input_shapes</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">default_input</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">function</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">projections</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">combine</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">weight</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">exponent</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">internal_only</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">params</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">name</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">prefs</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">context</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.ports.inputport.InputPort" title="Link to this definition">¶</a></dt>
---
> <em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.components.ports.inputport.</span></span><span class="sig-name descname"><span class="pre">InputPort</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">owner</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">reference_value</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">variable</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">input_shapes</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">default_input</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">function</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">projections</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">combine</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">weight</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">exponent</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">internal_only</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">params</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">name</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">prefs</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">context</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">element_names</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.ports.inputport.InputPort" title="Link to this definition">¶</a></dt>
719a720,726
> <li><p><strong>element_names</strong> (<em>list</em><em> of </em><em>str : default None</em>) – optional semantic labels for each element of the InputPort’s
> <a class="reference internal" href="#psyneulink.core.components.ports.inputport.InputPort.value" title="psyneulink.core.components.ports.inputport.InputPort.value"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">value</span></code></a>, surfaced by the <code class="xref any docutils literal notranslate"><span class="pre">_debugger</span></code>
> NODE_EXECUTION snapshot and consumed by inspection tools. The
> list length must equal the size of the port’s value; a mismatch
> raises a <a class="reference internal" href="Port.html#psyneulink.core.components.ports.port.PortError" title="psyneulink.core.components.ports.port.PortError"><code class="xref any py py-exc docutils literal notranslate"><span class="pre">PortError</span></code></a> at construction. Stored as a static,
> read-only structural <a class="reference internal" href="Parameters.html#psyneulink.core.globals.parameters.Parameter" title="psyneulink.core.globals.parameters.Parameter"><code class="xref any py py-class docutils literal notranslate"><span class="pre">Parameter</span></code></a> that does not participate in
> execution.</p></li>
880a888,899
> <dt class="sig sig-object py" id="psyneulink.core.components.ports.inputport.InputPort.element_names">
> <span class="sig-name descname"><span class="pre">element_names</span></span><a class="headerlink" href="#psyneulink.core.components.ports.inputport.InputPort.element_names" title="Link to this definition">¶</a></dt>
> <dd><p>the value passed to the <strong>element_names</strong> argument of the constructor (or <code class="docutils literal notranslate"><span class="pre">None</span></code> if unset). See the
> argument description for usage and validation rules.</p>
> <dl class="field-list simple">
> <dt class="field-odd">Type<span class="colon">:</span></dt>
> <dd class="field-odd"><p>list of str or None</p>
> </dd>
> </dl>
> </dd></dl>
> 
> <dl class="py attribute">
1107a1127
> <li><a class="reference internal" href="#psyneulink.core.components.ports.inputport.InputPort.element_names"><code class="docutils literal notranslate"><span class="pre">InputPort.element_names</span></code></a></li>
diff -r docs-base/Mechanism.html docs-head/Mechanism.html
1058a1059,1068
> <li><p><strong>element_names</strong> (<em>list</em><em> of </em><em>str : default None</em>) – Mechanism-level shorthand that assigns semantic labels to each
> element of the Mechanism’s default (primary) <a class="reference internal" href="InputPort.html"><span class="doc">InputPort</span></a> <em>and</em>
> default <a class="reference internal" href="OutputPort.html"><span class="doc">OutputPort</span></a>, but only when those ports don’t already
> carry their own <code class="docutils literal notranslate"><span class="pre">element_names</span></code>. Equivalent to passing
> <code class="docutils literal notranslate"><span class="pre">element_names=[...]</span></code> to both ports individually; per-port
> labels always win if both are supplied. Distinct from
> <strong>input_labels</strong> / <strong>output_labels</strong>, which map symbolic names
> to value vectors. The list length must equal the size of the
> default port’s value; a mismatch raises a <a class="reference internal" href="Port.html#psyneulink.core.components.ports.port.PortError" title="psyneulink.core.components.ports.port.PortError"><code class="xref any py py-exc docutils literal notranslate"><span class="pre">PortError</span></code></a> at
> construction.</p></li>
diff -r docs-base/OutputPort.html docs-head/OutputPort.html
651c651
< <em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.components.ports.outputport.</span></span><span class="sig-name descname"><span class="pre">OutputPort</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">owner</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">reference_value</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">variable</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">input_shapes</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">function</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">projections</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">params</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">name</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">prefs</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">index</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">assign</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.ports.outputport.OutputPort" title="Link to this definition">¶</a></dt>
---
> <em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.components.ports.outputport.</span></span><span class="sig-name descname"><span class="pre">OutputPort</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">owner</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">reference_value</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">variable</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">input_shapes</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">function</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">projections</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">params</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">name</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">prefs</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">index</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre
...

See CI logs for the full diff.

element_names is a registered Parameter, so it serializes into a port's MDF
model automatically. Lock in the export behavior: explicit per-port labels
(input + output), the Mechanism shorthand, and the unset case (serializes as
None, consistent with the sibling structural params). Full script round-trip
is a tracked follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

This PR causes the following changes to the html docs (ubuntu-latest-3.11):

diff -r docs-base/InputPort.html docs-head/InputPort.html
686c686
< <em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.components.ports.inputport.</span></span><span class="sig-name descname"><span class="pre">InputPort</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">owner</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">reference_value</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">variable</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">input_shapes</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">default_input</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">function</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">projections</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">combine</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">weight</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">exponent</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">internal_only</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">params</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">name</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">prefs</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">context</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.ports.inputport.InputPort" title="Link to this definition">¶</a></dt>
---
> <em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.components.ports.inputport.</span></span><span class="sig-name descname"><span class="pre">InputPort</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">owner</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">reference_value</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">variable</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">input_shapes</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">default_input</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">function</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">projections</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">combine</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">weight</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">exponent</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">internal_only</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">params</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">name</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">prefs</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">context</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">element_names</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.ports.inputport.InputPort" title="Link to this definition">¶</a></dt>
719a720,726
> <li><p><strong>element_names</strong> (<em>list</em><em> of </em><em>str : default None</em>) – optional semantic labels for each element of the InputPort’s
> <a class="reference internal" href="#psyneulink.core.components.ports.inputport.InputPort.value" title="psyneulink.core.components.ports.inputport.InputPort.value"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">value</span></code></a>, surfaced by the <code class="xref any docutils literal notranslate"><span class="pre">_debugger</span></code>
> NODE_EXECUTION snapshot and consumed by inspection tools. The
> list length must equal the size of the port’s value; a mismatch
> raises a <a class="reference internal" href="Port.html#psyneulink.core.components.ports.port.PortError" title="psyneulink.core.components.ports.port.PortError"><code class="xref any py py-exc docutils literal notranslate"><span class="pre">PortError</span></code></a> at construction. Stored as a static,
> read-only structural <a class="reference internal" href="Parameters.html#psyneulink.core.globals.parameters.Parameter" title="psyneulink.core.globals.parameters.Parameter"><code class="xref any py py-class docutils literal notranslate"><span class="pre">Parameter</span></code></a> that does not participate in
> execution.</p></li>
880a888,899
> <dt class="sig sig-object py" id="psyneulink.core.components.ports.inputport.InputPort.element_names">
> <span class="sig-name descname"><span class="pre">element_names</span></span><a class="headerlink" href="#psyneulink.core.components.ports.inputport.InputPort.element_names" title="Link to this definition">¶</a></dt>
> <dd><p>the value passed to the <strong>element_names</strong> argument of the constructor (or <code class="docutils literal notranslate"><span class="pre">None</span></code> if unset). See the
> argument description for usage and validation rules.</p>
> <dl class="field-list simple">
> <dt class="field-odd">Type<span class="colon">:</span></dt>
> <dd class="field-odd"><p>list of str or None</p>
> </dd>
> </dl>
> </dd></dl>
> 
> <dl class="py attribute">
1107a1127
> <li><a class="reference internal" href="#psyneulink.core.components.ports.inputport.InputPort.element_names"><code class="docutils literal notranslate"><span class="pre">InputPort.element_names</span></code></a></li>
diff -r docs-base/Mechanism.html docs-head/Mechanism.html
1058a1059,1068
> <li><p><strong>element_names</strong> (<em>list</em><em> of </em><em>str : default None</em>) – Mechanism-level shorthand that assigns semantic labels to each
> element of the Mechanism’s default (primary) <a class="reference internal" href="InputPort.html"><span class="doc">InputPort</span></a> <em>and</em>
> default <a class="reference internal" href="OutputPort.html"><span class="doc">OutputPort</span></a>, but only when those ports don’t already
> carry their own <code class="docutils literal notranslate"><span class="pre">element_names</span></code>. Equivalent to passing
> <code class="docutils literal notranslate"><span class="pre">element_names=[...]</span></code> to both ports individually; per-port
> labels always win if both are supplied. Distinct from
> <strong>input_labels</strong> / <strong>output_labels</strong>, which map symbolic names
> to value vectors. The list length must equal the size of the
> default port’s value; a mismatch raises a <a class="reference internal" href="Port.html#psyneulink.core.components.ports.port.PortError" title="psyneulink.core.components.ports.port.PortError"><code class="xref any py py-exc docutils literal notranslate"><span class="pre">PortError</span></code></a> at
> construction.</p></li>
diff -r docs-base/OutputPort.html docs-head/OutputPort.html
651c651
< <em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.components.ports.outputport.</span></span><span class="sig-name descname"><span class="pre">OutputPort</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">owner</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">reference_value</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">variable</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">input_shapes</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">function</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">projections</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">params</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">name</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">prefs</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">index</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">assign</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.ports.outputport.OutputPort" title="Link to this definition">¶</a></dt>
---
> <em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.components.ports.outputport.</span></span><span class="sig-name descname"><span class="pre">OutputPort</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">owner</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">reference_value</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">variable</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">input_shapes</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">function</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">projections</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">params</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">name</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">prefs</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">index</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre
...

See CI logs for the full diff.

The 'notorch' CI config doesn't install modeci_mdf, so as_mdf_model() raises
ModuleNotFoundError. Guard the module with pytest.importorskip('modeci_mdf'),
matching tests/mdf/test_mdf.py.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jonhanke-nam
jonhanke-nam marked this pull request as ready for review August 19, 2026 22:55
@jonhanke-nam

Copy link
Copy Markdown
Collaborator Author

Ready for review. Full CI is green (build matrix across Python 3.10–3.14 × macOS/Ubuntu/Windows incl. LLVM/benchmark/notorch, docs, CodeQL, coverage). Any red/gray marks in the checks list are cancelled push-event runs that GitHub superseded when the PR runs started — not failures; the pull_request runs all passed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants