Parent
#8
What to build
Replace the current "method always exists, raises NotImplementedError at call time" pattern with feature-gated method binding: on Namespaces whose libcbv2g schema doesn't define *_exiFragment or xmldsigFragment roots (today: SAP, DIN), the corresponding EXIProcessor methods (encode_fragment, decode_fragment, encode_xmldsig, decode_xmldsig) are absent — accessing them raises AttributeError, and hasattr(p, "encode_fragment") returns False.
Today the binders in _bind_decoder / _bind_encoder silently skip missing ctypes symbols and the Python methods raise NotImplementedError mentioning the internal ctypes symbol name. The new behavior makes feature detection honest: a consumer can hasattr to dispatch instead of try/except.
Implementation: EXIProcessor.__init__ should conditionally bind the Fragment / XmldsigFragment methods to the instance only when the underlying ctypes symbol exists. Methods on the class continue to exist for type-checker visibility, but instances of SAP/DIN Processors don't carry them — or alternatively, the class-level methods are removed entirely and the implementation lives in instance-bound closures gated by the ctypes-symbol check. Either is acceptable; choose the simpler.
Update tests/integration/test_namespace_parity.py and tests/integration/test_unsupported_methods.py accordingly: the expectation flips from "calling the method on SAP/DIN raises NotImplementedError" to "the method is not present on SAP/DIN processors; hasattr returns False and accessing the attribute raises AttributeError".
Per ADR-0014 supersedes ADR-0006 lines 12 and 21 on this point.
Acceptance criteria
Blocked by
Parent
#8
What to build
Replace the current "method always exists, raises
NotImplementedErrorat call time" pattern with feature-gated method binding: on Namespaces whose libcbv2g schema doesn't define*_exiFragmentorxmldsigFragmentroots (today: SAP, DIN), the correspondingEXIProcessormethods (encode_fragment,decode_fragment,encode_xmldsig,decode_xmldsig) are absent — accessing them raisesAttributeError, andhasattr(p, "encode_fragment")returnsFalse.Today the binders in
_bind_decoder/_bind_encodersilently skip missing ctypes symbols and the Python methods raiseNotImplementedErrormentioning the internal ctypes symbol name. The new behavior makes feature detection honest: a consumer canhasattrto dispatch instead of try/except.Implementation:
EXIProcessor.__init__should conditionally bind the Fragment / XmldsigFragment methods to the instance only when the underlying ctypes symbol exists. Methods on the class continue to exist for type-checker visibility, but instances of SAP/DIN Processors don't carry them — or alternatively, the class-level methods are removed entirely and the implementation lives in instance-bound closures gated by the ctypes-symbol check. Either is acceptable; choose the simpler.Update
tests/integration/test_namespace_parity.pyandtests/integration/test_unsupported_methods.pyaccordingly: the expectation flips from "calling the method on SAP/DIN raisesNotImplementedError" to "the method is not present on SAP/DIN processors;hasattrreturns False and accessing the attribute raisesAttributeError".Per ADR-0014 supersedes ADR-0006 lines 12 and 21 on this point.
Acceptance criteria
EXIProcessorinstances forNamespace.SAPandNamespace.DINlackencode_fragment,decode_fragment,encode_xmldsig,decode_xmldsigattributeshasattr(EXIProcessor(Namespace.ISO2), "encode_fragment")returnsTrue; same for the five ISO-20 Namespacesencode_fragmenton a SAP/DIN processor raisesAttributeError(notNotImplementedError)tests/integration/test_namespace_parity.pyupdated — parity expectations match feature gatingtests/integration/test_unsupported_methods.pyupdated — assertsAttributeError, notNotImplementedErrorBlocked by