Skip to content

feat: keep SPEC-RELATION and RELATION-GROUP attribute values - #228

Merged
stanislaw merged 1 commit into
strictdoc-project:mainfrom
fNBU:fix/spec-relation-relation-group-values
Aug 10, 2026
Merged

feat: keep SPEC-RELATION and RELATION-GROUP attribute values#228
stanislaw merged 1 commit into
strictdoc-project:mainfrom
fNBU:fix/spec-relation-relation-group-values

Conversation

@fNBU

@fNBU fNBU commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

@stanislaw, one part of this fix (SPEC-RELATION) is an ordinary bug fix, but the other part (RELATION-GROUP) reads and writes an element the bundled reqif.xsd rejects. The latter needs your consideration.

SPEC-RELATION

ReqIFSpecRelation modelled <VALUES> as values_attribute, a single value, and the parser's loop breaks after the first child, so a relation with two values kept only the first. That loop handled just STRING, INTEGER and XHTML, raising NotImplementedError on the other four kinds, so on current main a SPEC-RELATION carrying a BOOLEAN, DATE, REAL or ENUMERATION value does not lose data, it fails to parse at all.

RELATION-GROUP

ReqIFRelationGroup had no field for <VALUES> at all, so those values were dropped on parse and never written. Adding them runs into the schema:

complexType <VALUES> permitted?
SPEC-OBJECT yes
SPEC-RELATION yes
RELATION-GROUP no

The asymmetry is a defect: the spec PDF's MOF model (10.8.33) defines values on RelationGroup and the XSD omits them. From the prostep ivip ReqIF Implementation Guide v1.8, section 2.11 (p. 20):

Due to a bug in the current ReqIF XML schema, it is possible to assign a RelationGroupType (including AttributeDefinition elements) to a RelationGroup element, but it is not possible to assign AttributeValue elements to the RelationGroup. As this may lead to inconsistencies, the current recommendation is not to add any AttributeDefinition elements to a RelationGroupType instance.

That advice is aimed at whoever authors the content, and says nothing about what an importing tool should do with a file that already contains the element. #214 (merged as cd6c4ad) also added attribute_definitions to ReqIFRelationGroupType, so reqif can already express a relation group type with attribute definitions but cannot carry the matching values. That is the inconsistency 2.11 warns about, and closing it the other way would mean reverting #214.

Validation is unaffected: validate --use-reqif-schema still reports one schema issue on such a file and zero on a conformant one.

Permissive on import, warning on export

Sections 2.1, 2.3 and 2.13 of the guide all ask importing tools to be forgiving about what they read and keep the strictness on the export side. Refusing to parse the element would make reqif less compliant with the guide, not more, so nothing warns on parse.

Export is where the strictness belongs. So unparse logs a warning naming the group, once per group per write. A caller who adds VALUES to a group that did not have them hears about it, then decides whether to ship an XSD-invalid file. They know more about their use case; a library that refused to write the element would make that call for them.

Callers who have made the call can silence the warning the usual way, with no change to the output:

logging.getLogger("reqif.parsers.relation_group_parser").setLevel(logging.ERROR)

Tests

test_spec_relation_parser.py covers mixed values surviving parse and unparse (including the previously fatal BOOLEAN) and the deprecated accessor. test_relation_group_parser.py is new, the first unit coverage for that parser: values survive, a group without values does not grow a VALUES element, and the warning fires once, names the group, stays off during parse, and can be suppressed. invoke check is clean, integration 78 passed with 1 unsupported and 0 failed.

If you'd prefer hard refusal to emit xsd-invalid (but spec-valid) reqif, I can implement that (our project will have to monkeypatch around it).

RELATION-GROUP had no model field for <VALUES> at all, so every attribute
value on a relation group was dropped on parse and never emitted.

SPEC-RELATION had `values_attribute`, holding at most one value: the parser
`break`s after the first child of <VALUES>, so any further values were
dropped. That hand-rolled loop also covered only STRING, INTEGER and XHTML
and raised NotImplementedError on the other four ATTRIBUTE-VALUE-* kinds,
so a SPEC-RELATION carrying a BOOLEAN, DATE, REAL or ENUMERATION value
failed to parse outright.

Both now carry `values: Optional[List[SpecObjectAttribute]]` and delegate to
AttributeValueParser.parse_attribute_values / unparse_attribute_values, the
same helpers SPEC-OBJECT and SPECIFICATION already use, so all seven value
kinds and XML comments are handled in one place.

`ReqIFSpecRelation.values_attribute` is kept as a deprecated property over
`values` (reading the first value, writing replacing all of them) so
existing callers keep working; passing both it and `values` to the
constructor is rejected.

The XSD permits VALUES on SPEC-RELATION, so that half only implements what
the schema already allows. It does not permit VALUES on RELATION-GROUP,
although the ReqIF spec PDF's MOF model (10.8.33) defines it. This is a known
defect of the ReqIF XML schema, called out as such in the prostep ivip ReqIF
Implementation Guide v1.8, section 2.11:

  https://www.ps-ent-2023.de/fileadmin/prod-download/prostep-ivip_ImplementationGuide_ReqIF_V1-8.pdf

That section's advice is addressed to whoever authors the content and says
nothing about what an importing tool should do with a file that already
carries the element. Sections 2.1, 2.3 and 2.13 do speak to tools, and ask
importing tools to be forgiving about what they read while keeping the
strictness on the export side. Parsing the element therefore stays silent.

Writing it is a deliberate deviation from the schema, so the unparser logs a
warning naming the RELATION-GROUP, once per group per write. Whether to ship
an XSD-invalid file is the caller's decision, since the caller knows which
tools will read the output; refusing to write the element would make that
decision for them. Callers who have made it can silence the warning through
the standard logging hierarchy, with no reqif-specific API and no change to
the output:

  logging.getLogger("reqif.parsers.relation_group_parser").setLevel(logging.ERROR)

This works because reqif/__init__.py already follows the library convention
of attaching a NullHandler to the package logger.

Validation is untouched and continues to follow the XSD: a file carrying such
values reports one schema issue under `reqif validate --use-reqif-schema`,
before and after a write, and a conformant file reports none. VALUES is
emitted first, mirroring SPEC-OBJECT's child order; RELATION-GROUP is an
xsd:all, so the position carries no meaning. No existing test fixture puts
VALUES on a RELATION-GROUP, so current integration output is unchanged.

Also annotate unparse_attribute_values as returning str; without it mypy
--strict reports the new call site as returning Any.
@fNBU
fNBU force-pushed the fix/spec-relation-relation-group-values branch from 975aa3b to 809dd32 Compare August 3, 2026 02:18

@stanislaw stanislaw left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This seems to be fine as you suggested. It is a good compromise given the bug in the xsd spec.

@stanislaw
stanislaw merged commit 75ecd7b into strictdoc-project:main Aug 10, 2026
6 checks 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.

2 participants