ifctester: two false passes in prohibited property checks - #9274
Open
BIMvoice wants to merge 2 commits into
Open
ifctester: two false passes in prohibited property checks#9274BIMvoice wants to merge 2 commits into
BIMvoice wants to merge 2 commits into
Conversation
Property.__call__ filtered out empty string property values before deciding pset/property existence, so a PROHIBITED property set to "" (present but empty) was treated as absent and silently passed. property-facet.md is explicit that a prohibited property "must not exist... even if empty", matching the sibling fix already applied to Attribute. Property now checks raw existence before that filtering, only for the no-value prohibited case, leaving REQUIRED and OPTIONAL untouched. Generated with the assistance of an AI coding tool.
A prohibited Property requirement with a pattern-matched propertySet checked each matching pset independently with a fresh probe instead of sharing one pass flag, so an earlier pset's absence or mismatch could no longer mask a later pset that actually held the value. Sibling of the empty-value fix already in this branch: that guard covers prohibited without a value, this one covers prohibited with a value, split cleanly on whether self.value is set. Generated with the assistance of an AI coding tool.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two distinct false passes in
Property.__call__'s prohibited branch. Both let a violation report as compliant, which is the worst direction for a checker to be wrong in, since nothing prompts anyone to look again.1. Present but empty looks absent
Property.__call__filters empty string values out before deciding whether the property exists:then the prohibited branch reuses that filtered result. So a property that is present but empty looks absent, and a
prohibitedrequirement silently passes.property-facet.mdis explicit that a prohibited property must not exist even if empty. That filtering is correct for REQUIRED and OPTIONAL, which legitimately treat empty as not populated, and reusing it for prohibited is what inverts a violation into a pass.This is the
Propertysibling of #9273, which fixed the same shape inAttribute.2. Cross-pset masking when a value is required
A separate bug in the same branch, only when
valueis set. With a patternpropertySetmatching several psets, the loop shared oneis_passaccumulator across all of them. An earlier pset lacking the property, or holding a mismatching value, droveis_passto False permanently. A later pset holding exactly the prohibited value never flipped it back, because a value match only leftis_passunchanged rather than setting it.Proven distinct rather than a restatement: tested against this PR's own previous head, with the fix for defect 1 already in place, and it still failed identically.
Fixed by checking each matching pset independently, split cleanly on whether
self.valueis set, so the two guards together cover every prohibited case before the shared loop runs. It reuses the existing single-pset value, dataType and unit matching by probing a shallow copy rather than duplicating that logic, which leaves the main loop untouched.Sibling sweep
Every facet with a cardinality branch, not just this one:
AttributePropertyClassificationbool(references), no filteringPartOfis not Noneon relationship objectsMaterialis not Nonefromget_materialEntityClassificationis the reference pattern: existence is checked before any filtering.Overlap with other open PRs
optionalbranch's escape hatch. Whoever merges should know they are sibling fixes to the same method.IfcPropertyBoundedValuehandling further down.Tests
Two fixture directories,
property_prohibited_empty_string/andproperty_prohibited_multi_pset/, each with its own test file.test_facet.pydeliberately untouched, since several of our other open ifctester PRs already modify it.Red before each fix, failing for the right reason in both cases:
Green after. Full ifctester suite 43/43.
Produced with AI assistance.