Skip to content

Make label, description, and value optional on all attribute constructors#3009

Draft
fabiencastan wants to merge 3 commits intoalicevision:developfrom
fabiencastan:copilot/make-label-description-optional
Draft

Make label, description, and value optional on all attribute constructors#3009
fabiencastan wants to merge 3 commits intoalicevision:developfrom
fabiencastan:copilot/make-label-description-optional

Conversation

@fabiencastan
Copy link
Member

Attribute constructors previously required explicit label, description, and value arguments. All three are now optional with sensible defaults, reducing boilerplate in node definitions.

# Before
desc.IntParam(name="nbPoints", label="Nb Points", description="", value=0, range=(0, 1000, 1))

# After
desc.IntParam(name="nbPoints", range=(0, 1000, 1))

Description

Makes label, description, and value optional on all attribute descriptor constructors (File, BoolParam, IntParam, FloatParam, StringParam, ColorParam, ChoiceParam, ListAttribute, GroupAttribute).

Features list

  • label=None — auto-generated from name via camelCase/snake_case → Title Case (e.g. nbPoints"Nb Points", my_attr"My Attr")
  • description=None — defaults to ""
  • value=None on all param types:
    • Output attributes: isDynamicValue=True (dynamic, computed at runtime) — consistent with prior explicit value=None behavior
    • Input attributes: resolved to type's zero-value (int()→0, float()→0.0, bool()→False, str()→"")

Implementation remarks

  • _labelFromName(name) in desc/attribute.py: regex inserts spaces at camelCase boundaries, underscores replaced with spaces, then title-cased.
  • Input default resolution is in Attribute.getDefaultValue() (core/attribute.py): when _desc.value is None and isInput and _valueType is not None, returns _desc._valueType() instead of None.
  • checkValueTypes() updated for all affected types to treat value=None as valid (no type error flagged).
  • ChoiceParam.__init__ guarded with is not None (was using truthiness, which broke on empty list values with exclusive=False).
  • Added checkValueTypes() to ColorParam, which was previously missing.

Copilot AI and others added 3 commits February 21, 2026 10:43
… label from name

Co-authored-by: fabiencastan <153585+fabiencastan@users.noreply.github.com>
…ault

Co-authored-by: fabiencastan <153585+fabiencastan@users.noreply.github.com>
@codecov
Copy link

codecov bot commented Feb 21, 2026

Codecov Report

❌ Patch coverage is 90.52632% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.06%. Comparing base (43a24bb) to head (1302d30).

Files with missing lines Patch % Lines
meshroom/core/desc/attribute.py 76.92% 9 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3009      +/-   ##
===========================================
+ Coverage    81.99%   82.06%   +0.07%     
===========================================
  Files           69       69              
  Lines         9315     9396      +81     
===========================================
+ Hits          7638     7711      +73     
- Misses        1677     1685       +8     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR reduces boilerplate in Meshroom node attribute descriptors by making label, description, and value optional across attribute constructors, with defaults derived from the attribute name and type-specific default values for inputs.

Changes:

  • Added _labelFromName(name) and updated descriptor constructors to auto-generate label and default description to "".
  • Updated descriptor checkValueTypes() implementations to treat value=None as valid for affected attribute types.
  • Updated runtime input default resolution (Attribute.getDefaultValue) and added tests covering the new defaults.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
meshroom/core/desc/attribute.py Makes descriptor ctor args optional; adds name→label generation; relaxes type checks for value=None; updates ChoiceParam / adds ColorParam.checkValueTypes().
meshroom/core/attribute.py Changes runtime default-value resolution for input attributes when descriptor value is None.
tests/test_attributes.py Adds tests for label generation and new default behaviors for input/output attributes when descriptor value=None.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -1,4 +1,7 @@
from meshroom.core.graph import Graph
from meshroom.core import desc as coreDesc
from meshroom.core.desc.attribute import _labelFromName, StringParam, IntParam, FloatParam, BoolParam, File, ListAttribute, GroupAttribute
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ListAttribute and GroupAttribute are imported here but not used in this test module. Consider removing them to avoid unused imports and keep the test focused.

Suggested change
from meshroom.core.desc.attribute import _labelFromName, StringParam, IntParam, FloatParam, BoolParam, File, ListAttribute, GroupAttribute
from meshroom.core.desc.attribute import _labelFromName, StringParam, IntParam, FloatParam, BoolParam, File

Copilot uses AI. Check for mistakes.
Comment on lines +304 to +305
# value type, use the type's default constructor value (e.g. 0 for int, "" for str).
if self._desc.value is None and self.isInput and self._desc._valueType is not None:
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getDefaultValue() uses self._desc._valueType() when desc.value is None. For desc.ChoiceParam with exclusive=False, _valueType is the element type (e.g. str), so this produces "", which then gets validated into [""] for the attribute default. This breaks the expected empty-list default for non-exclusive ChoiceParams and can lead to incorrect CLI formatting/serialization behavior. Consider special-casing non-exclusive ChoiceParam to default to an empty list (and add a regression test).

Suggested change
# value type, use the type's default constructor value (e.g. 0 for int, "" for str).
if self._desc.value is None and self.isInput and self._desc._valueType is not None:
# value type, use the type's default constructor value (e.g. 0 for int, "" for str),
# except for non-exclusive ChoiceParam, which should default to an empty list.
if self._desc.value is None and self.isInput and self._desc._valueType is not None:
if isinstance(self._desc, desc.ChoiceParam) and not getattr(self._desc, "exclusive", True):
return []

Copilot uses AI. Check for mistakes.
Comment on lines 515 to 516
# if non exclusive, it is a list
self._valueType = type(self._value[0])
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In ChoiceParam.__init__, when exclusive=False and value is provided as an empty list, type(self._value[0]) will raise IndexError. Empty selections (value=[]) are a valid default for non-exclusive ChoiceParams, so this should be handled (e.g., derive the type from values when available, or fall back to None when the list is empty).

Suggested change
# if non exclusive, it is a list
self._valueType = type(self._value[0])
# if non exclusive, it is a list; use the first element when available
if self._value:
self._valueType = type(self._value[0])
else:
# Empty selection: element type cannot be inferred yet
self._valueType = None

Copilot uses AI. Check for mistakes.
Comment on lines +497 to 500
def __init__(self, name, label=None, description=None, value=None, values=None, exclusive=True, saveValuesOverride=False,
group="allParams", joinChar=" ", advanced=False, enabled=True, invalidate=True, semantic="",
validValue=True, errorMessage="",
visible=True, exposed=False):
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constructor now defaults values=None, making ChoiceParam instantiable without any values. This is likely accidental (the PR description only mentions label/description/value becoming optional) and can lead to runtime failures because _valueType may remain None. Consider keeping values required (no default) or raising a clear error when values is not provided.

Copilot uses AI. Check for mistakes.
Comment on lines 553 to 560
def checkValueTypes(self):
# A None value is valid and means "use the type default"
if self._value is None:
return "", ValueTypeErrors.NONE

# Check that the values have been provided as a list
if not isinstance(self._values, list):
return self.name, ValueTypeErrors.TYPE
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ChoiceParam.checkValueTypes() returns early when _value is None, which means it no longer validates that _values is a list. As a result, misconfigured descriptors (e.g. values=None or a non-list) won't be flagged by checkValueTypes() even though they can break validation/conformance later. Consider still validating _values (or explicitly allowing None with a dedicated error/behavior).

Copilot uses AI. Check for mistakes.
@fabiencastan fabiencastan marked this pull request as draft February 27, 2026 17:21
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