Source
Bernhard's mat-vis#311 — sub-bullet "Inconsistent outputs".
MorePET/mat-vis#311
Reported against pymat 3.10.0. Bug persists on current dev (35681ce) — Vis is a @dataclass with no custom __repr__, so the auto-generated repr keeps showing identity-time field values (which are all None until the user explicitly overrides them). Version line is provenance only.
Problem
Vis is a lazy API: scalar fields stay None until .textures / .to_threejs() triggers a fetch. After fetch, the repr is still all-None even though the data is loaded — the user has no signal that anything happened.
Repro
v = Vis(source="gpuopen", material_id="Aluminum Brushed", tier="1k")
v
# Vis(source='gpuopen', material_id='Aluminum Brushed', tier='1k', finishes={},
# roughness=None, metallic=None, base_color=None, ior=None, transmission=None, ...)
t = v.to_threejs() # fetches!
t["metalness"], t["roughness"]
# (1.0, 0.4) ← data is there
v
# Vis(source='gpuopen', material_id='Aluminum Brushed', tier='1k', finishes={},
# roughness=None, metallic=None, base_color=None, ior=None, transmission=None, ...)
# ← still all None
print(v.metallic)
# None
Bernhard's expectation:
v # before fetch
# Vis(source='gpuopen', material_id='Aluminum Brushed', tier='1k', finishes={}, fetched=False)
v.textures # triggers fetch
v # after fetch
# Vis(source='gpuopen', material_id='Aluminum Brushed', tier='1k', finishes={},
# roughness=0.4, metallic=1.0, base_color="#cccccc", ior=1.5, transmission=0,
# available_textures=['color', 'normal', 'roughness'])
Root cause
The Vis dataclass declares fields like roughness: float | None = None for caller overrides, not for cached fetched values. Cached values live in _textures / _fetched (private), and the catalog's authored scalars are read on demand via the adapter — they never populate the dataclass fields.
So the repr is technically truthful ("the user hasn't overridden these"), but for the user it reads as "nothing is loaded." Two valid framings collide.
Options
- Minimal: Repr-only change — show
fetched=True/False flag. Don't touch field semantics.
- Medium: When
_fetched=True, the repr also shows the authored scalars from the catalog (read via the proposed Vis.scalars accessor — see related issue).
- Heavier: Populate the dataclass fields after fetch (semantic change — overrides become indistinguishable from authored values).
Recommendation
(1) + (2): show fetched=True, plus inline a scalars=... summary when fetched. Keeps the override/authored distinction honest while giving the user a visible signal.
Acceptance
Related
- mat#220 (
Vis.scalars accessor — this issue assumes it exists)
Source
Bernhard's mat-vis#311 — sub-bullet "Inconsistent outputs".
MorePET/mat-vis#311
Problem
Visis a lazy API: scalar fields stayNoneuntil.textures/.to_threejs()triggers a fetch. After fetch, the repr is still all-None even though the data is loaded — the user has no signal that anything happened.Repro
Bernhard's expectation:
Root cause
The
Visdataclass declares fields likeroughness: float | None = Nonefor caller overrides, not for cached fetched values. Cached values live in_textures/_fetched(private), and the catalog's authored scalars are read on demand via the adapter — they never populate the dataclass fields.So the repr is technically truthful ("the user hasn't overridden these"), but for the user it reads as "nothing is loaded." Two valid framings collide.
Options
fetched=True/Falseflag. Don't touch field semantics._fetched=True, the repr also shows the authored scalars from the catalog (read via the proposedVis.scalarsaccessor — see related issue).Recommendation
(1) + (2): show
fetched=True, plus inline ascalars=...summary when fetched. Keeps the override/authored distinction honest while giving the user a visible signal.Acceptance
repr(v)showsfetched=Falserepr(v)showsfetched=Trueplus ascalars=summary (oravailable_textures=)v.metallic = 0.7still surfaces in repr as the overrideRelated
Vis.scalarsaccessor — this issue assumes it exists)