mjcf: restore schema declarations lost in the schema.xml regeneration - #553
mjcf: restore schema declarations lost in the schema.xml regeneration#553shoemoney wants to merge 2 commits into
Conversation
The schema regeneration in 985d094 dropped three declarations that MuJoCo 3.12 still accepts, breaking previously working PyMJCF models: - sensor lost its contact child element, so parsing a model with <sensor><contact .../></sensor> raises KeyError while raw MuJoCo loads it fine. - jointinparent on the nine actuator elements degraded from type="reference" reference_namespace="joint" to type="string", so attach() no longer prefixes the joint name and the composed model fails to compile with "unknown transmission target". - custom/numeric data degraded from a float array to a string, so add('numeric', name='x', data=[1, 2, 3]) raises ValueError. Restore the three declarations as they were before the regeneration and add regression tests covering all three.
sylvesterkaczmarek
left a comment
There was a problem hiding this comment.
One attach-time namespace case is still missing: the restored contact sensor declares site as a plain reference. MuJoCo’s generated dm_control schema uses type="reference" reference_namespace="site". Without that namespace, attaching a child model with a contact sensor configured by site leaves the child site name unprefixed and can fail compilation, the same class of regression this PR fixes for jointinparent. Please restore reference_namespace="site" and add an attach regression for the site-based contact sensor path.
The restored contact sensor declared site as a bare type="reference" while every
sibling reference in the same element carried a namespace. It was the only bare
reference in the whole file, which makes it the odd one out against MuJoCo's own
generated schema and against the nine jointinparent declarations this PR exists
to restore.
The behavioral claim it was reported under does not hold, and the reason is
schema.py:152-153:
other_kwargs['reference_namespace'] = (
attribute_xml.get('reference_namespace') or name)
An absent namespace falls back to the attribute's own name, and the attribute is
named site, so the resolved namespace is "site" either way. Measured: attaching a
child whose contact sensor is configured by site produces byte-identical XML with
and without the declaration, the reference resolves to an _AttachableElement in
both cases, and it follows a rename of the target in both cases. So it does not
leave the child site unprefixed and cannot fail compilation.
That also means an attach regression for this cannot fail, so instead of shipping
one that only looks like verification, the added test asserts the invariant that
can actually break: no attribute of type="reference" may omit its namespace.
Without this commit it fails with ['site'] has length of 1. That is the same
class of loss as the jointinparent regression, caught on the file rather than on
one code path, so the next regeneration that drops a namespace is caught even
where the fallback happens to mask it.
schema_test.py: 8 passed.
|
Made the change in The change is right. The stated consequence does not reproduce. other_kwargs['reference_namespace'] = (
attribute_xml.get('reference_namespace') or name)An absent
So it does not fail compilation, and an attach regression for it passes with the bug present. I wrote the test you asked for first and it passed against the unfixed schema, which is the only reason I went looking for why. What I added instead asserts the invariant that can actually break: no attribute of The fallback is also why this was easy to miss when the element was restored, and why the file-level assertion seemed worth more than a per-attribute one. |
sylvesterkaczmarek
left a comment
There was a problem hiding this comment.
Rechecked de77a71f. You are right that the attach-time symptom I described is masked when the attribute name and fallback namespace are both site. Restoring the explicit namespace is still correct, and the file-level invariant that every reference declares its namespace is a stronger regression for this regeneration class. No remaining blocker from me.
Fixes #552.
The schema regeneration in 985d094 dropped three declarations that the pre-regeneration
schema.xmlcarried and that MuJoCo 3.12 still accepts. Each one breaks a previously working PyMJCF model at HEAD:sensorlost itscontactchild element. Parsing a model with<sensor><contact .../></sensor>raisesKeyErrorwhile raw MuJoCo loads the same XML.jointinparenton the nine actuator elements degraded fromtype="reference" reference_namespace="joint"totype="string".attach()therefore emits the joint name unprefixed and the composed model fails to compile withunknown transmission target.custom/numericdatadegraded fromtype="array" array_type="float"totype="string", soroot.custom.add('numeric', name='x', data=[1, 2, 3])raisesValueError.This PR restores the three declarations exactly as they were in the pre-regeneration schema and adds a
SchemaRegressionTesttoschema_test.pycovering all three (parse and compile of a contact sensor, attach round-trip that must scopejointinparent, and array data on a custom numeric). All three tests fail at HEAD and pass with the fix; the fulldm_control/mjcftest suite passes (157 tests).If the preferred fix is in the schema generator rather than the checked-in file, the regression tests here should transfer directly.