def inheritedAspectValue(view, aspect, xAspects, yAspects, zAspects, xOrdCntx, yOrdCntx): ords = xAspects.get(aspect, emptySet) | yAspects.get(aspect, emptySet) | zAspects.get(aspect, emptySet) structuralNode = None if len(ords) == 1: structuralNode = ords.pop() elif len(ords) > 1: if aspect == Aspect.LOCATION: hasClash = False for _ordCntx in ords: if not _ordCntx.definitionNode.aspectValueDependsOnVars(aspect): if structuralNode: hasClash = True else: structuralNode = _ordCntx else: hasClash = True if hasClash: from arelle.ModelFormulaObject import aspectStr view.modelXbrl.error("xbrlte:axisAspectClash", _("Aspect %(aspect)s covered by multiple axes."), modelObject=view.modelTable, aspect=aspectStr(aspect)) if structuralNode: definitionNode = structuralNode.definitionNode if definitionNode.aspectValueDependsOnVars(aspect): return xOrdCntx.evaluate(definitionNode, definitionNode.aspectValue, otherOrdinate=yOrdCntx, evalArgs=(aspect,)) return structuralNode.aspectValue(aspect) return None
def checkBreakdownLeafNodeAspects(modelXbrl, modelTable, tblAxisRel, aspectsCovered, breakdownAspects): definitionNode = tblAxisRel.toModelObject if isinstance(definitionNode, (ModelDefinitionNode, ModelEuAxisCoord)): for aspect in definitionNode.aspectsCovered(): aspectsCovered.add(aspect) definitionNodeHasChild = False for axisSubtreeRel in modelXbrl.relationshipSet((XbrlConst.tableBreakdownTree, XbrlConst.tableBreakdownTreeMMDD, XbrlConst.tableBreakdownTree201305, XbrlConst.tableDefinitionNodeSubtree, XbrlConst.tableDefinitionNodeSubtreeMMDD, XbrlConst.tableDefinitionNodeSubtree201305, XbrlConst.tableDefinitionNodeSubtree201301, XbrlConst.tableAxisSubtree2011)).fromModelObject(definitionNode): checkBreakdownLeafNodeAspects(modelXbrl, modelTable, axisSubtreeRel, aspectsCovered, breakdownAspects) definitionNodeHasChild = True if not definitionNode.isAbstract: # this is a leaf node missingAspects = set(aspect for aspect in breakdownAspects if aspect not in aspectsCovered and aspect != Aspect.DIMENSIONS and not isinstance(aspect,QName)) if (missingAspects): modelXbrl.error("xbrlte:missingAspectValue", _("%(definitionNode)s %(xlinkLabel)s does not define an aspect for %(aspect)s"), modelObject=(modelTable,definitionNode), xlinkLabel=definitionNode.xlinkLabel, definitionNode=definitionNode.localName, aspect=', '.join(aspectStr(aspect) for aspect in missingAspects))
def checkBreakdownLeafNodeAspects(modelXbrl, modelTable, tblAxisRel, parentAspectsCovered, breakdownAspects): definitionNode = tblAxisRel.toModelObject aspectsCovered = parentAspectsCovered.copy() if isinstance(definitionNode, (ModelDefinitionNode, ModelEuAxisCoord)): for aspect in definitionNode.aspectsCovered(): aspectsCovered.add(aspect) definitionNodeHasChild = False for axisSubtreeRel in modelXbrl.relationshipSet((XbrlConst.tableBreakdownTree, XbrlConst.tableBreakdownTreeMMDD, XbrlConst.tableBreakdownTree201305, XbrlConst.tableDefinitionNodeSubtree, XbrlConst.tableDefinitionNodeSubtreeMMDD, XbrlConst.tableDefinitionNodeSubtree201305, XbrlConst.tableDefinitionNodeSubtree201301, XbrlConst.tableAxisSubtree2011)).fromModelObject(definitionNode): checkBreakdownLeafNodeAspects(modelXbrl, modelTable, axisSubtreeRel, aspectsCovered, breakdownAspects) definitionNodeHasChild = True if not definitionNode.isAbstract and not isinstance(definitionNode, ModelBreakdown): # this is a leaf node missingAspects = set(aspect for aspect in breakdownAspects if aspect not in aspectsCovered and aspect != Aspect.DIMENSIONS and not isinstance(aspect,QName)) if (missingAspects): modelXbrl.error("xbrlte:missingAspectValue", _("%(definitionNode)s %(xlinkLabel)s does not define an aspect for %(aspect)s"), modelObject=(modelTable,definitionNode), xlinkLabel=definitionNode.xlinkLabel, definitionNode=definitionNode.localName, aspect=', '.join(aspectStr(aspect) for aspect in missingAspects))
def checkBreakdownDefinitionNode(modelXbrl, modelTable, tblAxisRel, tblAxisDisposition, uncoverableAspects, aspectsCovered): definitionNode = tblAxisRel.toModelObject hasCoveredAspect = False if isinstance(definitionNode, (ModelDefinitionNode, ModelEuAxisCoord)): for aspect in definitionNode.aspectsCovered(): aspectsCovered.add(aspect) if (aspect in uncoverableAspects or (isinstance(aspect, QName) and modelTable.aspectModel == 'non-dimensional')): modelXbrl.error( "xbrlte:axisAspectModelMismatch", _("%(definitionNode)s %(xlinkLabel)s, aspect model %(aspectModel)s, aspect %(aspect)s not allowed" ), modelObject=modelTable, definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel, aspectModel=modelTable.aspectModel, aspect=str(aspect) if isinstance(aspect, QName) else Aspect.label[aspect]) hasCoveredAspect = True if aspect in modelTable.priorAspectAxisDisposition: otherAxisDisposition, otherDefinitionNode = modelTable.priorAspectAxisDisposition[ aspect] if tblAxisDisposition != otherAxisDisposition and aspect != Aspect.DIMENSIONS: modelXbrl.error( "xbrlte:aspectClashBetweenBreakdowns", _("%(definitionNode)s %(xlinkLabel)s, aspect %(aspect)s defined on axes of disposition %(axisDisposition)s and %(axisDisposition2)s" ), modelObject=(modelTable, definitionNode, otherDefinitionNode), definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel, axisDisposition=tblAxisDisposition, axisDisposition2=otherAxisDisposition, aspect=str(aspect) if isinstance(aspect, QName) else Aspect.label[aspect]) else: modelTable.priorAspectAxisDisposition[aspect] = ( tblAxisDisposition, definitionNode) ruleSetChildren = XmlUtil.children(definitionNode, definitionNode.namespaceURI, "ruleSet") if definitionNode.isMerged: if ruleSetChildren: modelXbrl.error( "xbrlte:mergedRuleNodeWithTaggedRuleSet", _("Merged %(definitionNode)s %(xlinkLabel)s has tagged rule set(s)" ), modelObject=[modelTable, definitionNode] + ruleSetChildren, definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel) labelRels = modelXbrl.relationshipSet( XbrlConst.elementLabel).fromModelObject(definitionNode) if labelRels: modelXbrl.error( "xbrlte:invalidUseOfLabel", _("Merged %(definitionNode)s %(xlinkLabel)s has label(s)"), modelObject=[modelTable, definitionNode] + [r.toModelObject for r in labelRels], definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel) if not definitionNode.isAbstract: modelXbrl.error( "xbrlte:nonAbstractMergedRuleNode", _("Merged %(definitionNode)s %(xlinkLabel)s is not abstract" ), modelObject=(modelTable, definitionNode), definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel) if isinstance(definitionNode, ModelRuleDefinitionNode): tagConstraintSets = {} otherConstraintSet = None # must look at xml constructs for duplicates for ruleSet in XmlUtil.children(definitionNode, definitionNode.namespaceURI, "ruleSet"): tag = ruleSet.tagName if tag is not None: # named constraint sets only for aspect in ruleSet.aspectsCovered(): if aspect != Aspect.DIMENSIONS: modelTable.aspectsInTaggedConstraintSets.add(aspect) if tag in tagConstraintSets: modelXbrl.error( "xbrlte:duplicateTag", _("%(definitionNode)s %(xlinkLabel)s duplicate rule set tags %(tag)s" ), modelObject=(modelTable, definitionNode, tagConstraintSets[tag], ruleSet), definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel, tag=tag) else: tagConstraintSets[tag] = ruleSet for tag, constraintSet in definitionNode.constraintSets.items(): if otherConstraintSet is None: otherConstraintSet = constraintSet elif otherConstraintSet.aspectsCovered( ) != constraintSet.aspectsCovered(): modelXbrl.error( "xbrlte:constraintSetAspectMismatch", _("%(definitionNode)s %(xlinkLabel)s constraint set mismatches between %(tag1)s and %(tag2)s in constraints %(aspects)s" ), modelObject=(modelTable, definitionNode, otherConstraintSet, constraintSet), definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel, tag1=otherConstraintSet.tagName, tag2=constraintSet.tagName, aspects=", ".join( aspectStr(aspect) for aspect in otherConstraintSet.aspectsCovered() ^ constraintSet.aspectsCovered() if aspect != Aspect.DIMENSIONS)) if isinstance(definitionNode, ModelDimensionRelationshipDefinitionNode): hasCoveredAspect = True if modelTable.aspectModel == 'non-dimensional': modelXbrl.error( "xbrlte:axisAspectModelMismatch", _("DimensionRelationship axis %(xlinkLabel)s can't be used in non-dimensional aspect model" ), modelObject=(modelTable, definitionNode), xlinkLabel=definitionNode.xlinkLabel) definitionNodeHasChild = False for axisSubtreeRel in modelXbrl.relationshipSet( (XbrlConst.tableBreakdownTree, XbrlConst.tableBreakdownTreeMMDD, XbrlConst.tableBreakdownTree201305, XbrlConst.tableDefinitionNodeSubtree, XbrlConst.tableDefinitionNodeSubtreeMMDD, XbrlConst.tableDefinitionNodeSubtree201305, XbrlConst.tableDefinitionNodeSubtree201301, XbrlConst.tableAxisSubtree2011)).fromModelObject(definitionNode): if checkBreakdownDefinitionNode(modelXbrl, modelTable, axisSubtreeRel, tblAxisDisposition, uncoverableAspects, aspectsCovered): hasCoveredAspect = True # something below was covering definitionNodeHasChild = True if isinstance(definitionNode, ModelFilterDefinitionNode): for aspect in definitionNode.aspectsCovered(): if isinstance(aspect, QName): # dimension aspect concept = modelXbrl.qnameConcepts.get(aspect) if concept is None or not concept.isDimensionItem: modelXbrl.error( "xbrlte:invalidDimensionQNameOnAspectNode", _("Aspect node %(xlinkLabel)s dimensional aspect %(dimension)s is not a dimension" ), modelObject=(modelTable, definitionNode), xlinkLabel=definitionNode.xlinkLabel, dimension=aspect) if not definitionNodeHasChild: if (definitionNode.namespaceURI in ("http://www.eurofiling.info/2010/rendering", "http://xbrl.org/2011/table") and not hasCoveredAspect): modelXbrl.error( "xbrlte:aspectValueNotDefinedByOrdinate", _("%(definitionNode)s %(xlinkLabel)s does not define an aspect" ), modelObject=(modelTable, definitionNode), xlinkLabel=definitionNode.xlinkLabel, definitionNode=definitionNode.localName) if (isinstance(definitionNode, ModelClosedDefinitionNode) and definitionNode.isAbstract): modelXbrl.error( "xbrlte:abstractRuleNodeNoChildren", _("Abstract %(definitionNode)s %(xlinkLabel)s has no children" ), modelObject=(modelTable, definitionNode), xlinkLabel=definitionNode.xlinkLabel, definitionNode=definitionNode.localName) return hasCoveredAspect
def checkBreakdownDefinitionNode(modelXbrl, modelTable, tblAxisRel, tblAxisDisposition, uncoverableAspects, aspectsCovered): definitionNode = tblAxisRel.toModelObject hasCoveredAspect = False if isinstance(definitionNode, (ModelDefinitionNode, ModelEuAxisCoord)): for aspect in definitionNode.aspectsCovered(): aspectsCovered.add(aspect) if (aspect in uncoverableAspects or (isinstance(aspect, QName) and modelTable.aspectModel == 'non-dimensional')): modelXbrl.error("xbrlte:axisAspectModelMismatch", _("%(definitionNode)s %(xlinkLabel)s, aspect model %(aspectModel)s, aspect %(aspect)s not allowed"), modelObject=modelTable, definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel, aspectModel=modelTable.aspectModel, aspect=str(aspect) if isinstance(aspect,QName) else Aspect.label[aspect]) hasCoveredAspect = True if aspect in modelTable.priorAspectAxisDisposition: otherAxisDisposition, otherDefinitionNode = modelTable.priorAspectAxisDisposition[aspect] if tblAxisDisposition != otherAxisDisposition and aspect != Aspect.DIMENSIONS: modelXbrl.error("xbrlte:aspectClashBetweenBreakdowns", _("%(definitionNode)s %(xlinkLabel)s, aspect %(aspect)s defined on axes of disposition %(axisDisposition)s and %(axisDisposition2)s"), modelObject=(modelTable, definitionNode, otherDefinitionNode), definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel, axisDisposition=tblAxisDisposition, axisDisposition2=otherAxisDisposition, aspect=str(aspect) if isinstance(aspect,QName) else Aspect.label[aspect]) else: modelTable.priorAspectAxisDisposition[aspect] = (tblAxisDisposition, definitionNode) ruleSetChildren = XmlUtil.children(definitionNode, definitionNode.namespaceURI, "ruleSet") if definitionNode.isMerged: if ruleSetChildren: modelXbrl.error("xbrlte:mergedRuleNodeWithTaggedRuleSet", _("Merged %(definitionNode)s %(xlinkLabel)s has tagged rule set(s)"), modelObject=[modelTable, definitionNode] + ruleSetChildren, definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel) labelRels = modelXbrl.relationshipSet(XbrlConst.elementLabel).fromModelObject(definitionNode) if labelRels: modelXbrl.error("xbrlte:mergedRuleNodeWithLabel", _("Merged %(definitionNode)s %(xlinkLabel)s has label(s)"), modelObject=[modelTable, definitionNode] + [r.toModelObject for r in labelRels], definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel) if not definitionNode.isAbstract: modelXbrl.error("xbrlte:nonAbstractMergedRuleNode", _("Merged %(definitionNode)s %(xlinkLabel)s is not abstract"), modelObject=(modelTable, definitionNode), definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel) if isinstance(definitionNode, ModelRuleDefinitionNode): tagConstraintSets = {} otherConstraintSet = None # must look at xml constructs for duplicates for ruleSet in XmlUtil.children(definitionNode, definitionNode.namespaceURI, "ruleSet"): tag = ruleSet.tagName if tag is not None: # named constraint sets only for aspect in ruleSet.aspectsCovered(): if aspect != Aspect.DIMENSIONS: modelTable.aspectsInTaggedConstraintSets.add(aspect) if tag in tagConstraintSets: modelXbrl.error("xbrlte:duplicateTag", _("%(definitionNode)s %(xlinkLabel)s duplicate rule set tags %(tag)s"), modelObject=(modelTable, definitionNode, tagConstraintSets[tag], ruleSet), definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel, tag=tag) else: tagConstraintSets[tag] = ruleSet for tag, constraintSet in definitionNode.constraintSets.items(): if otherConstraintSet is None: otherConstraintSet = constraintSet elif otherConstraintSet.aspectsCovered() != constraintSet.aspectsCovered(): modelXbrl.error("xbrlte:constraintSetAspectMismatch", _("%(definitionNode)s %(xlinkLabel)s constraint set mismatches between %(tag1)s and %(tag2)s in constraints %(aspects)s"), modelObject=(modelTable, definitionNode, otherConstraintSet, constraintSet), definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel, tag1=otherConstraintSet.tagName, tag2=constraintSet.tagName, aspects=", ".join(aspectStr(aspect) for aspect in otherConstraintSet.aspectsCovered() ^ constraintSet.aspectsCovered() if aspect != Aspect.DIMENSIONS)) if isinstance(definitionNode, ModelDimensionRelationshipDefinitionNode): hasCoveredAspect = True if modelTable.aspectModel == 'non-dimensional': modelXbrl.error("xbrlte:axisAspectModelMismatch", _("DimensionRelationship axis %(xlinkLabel)s can't be used in non-dimensional aspect model"), modelObject=(modelTable,definitionNode), xlinkLabel=definitionNode.xlinkLabel) definitionNodeHasChild = False for axisSubtreeRel in modelXbrl.relationshipSet((XbrlConst.tableBreakdownTree, XbrlConst.tableBreakdownTreeMMDD, XbrlConst.tableBreakdownTree201305, XbrlConst.tableDefinitionNodeSubtree, XbrlConst.tableDefinitionNodeSubtreeMMDD, XbrlConst.tableDefinitionNodeSubtree201305, XbrlConst.tableDefinitionNodeSubtree201301, XbrlConst.tableAxisSubtree2011)).fromModelObject(definitionNode): if checkBreakdownDefinitionNode(modelXbrl, modelTable, axisSubtreeRel, tblAxisDisposition, uncoverableAspects, aspectsCovered): hasCoveredAspect = True # something below was covering definitionNodeHasChild = True if isinstance(definitionNode, ModelFilterDefinitionNode): for aspect in definitionNode.aspectsCovered(): if isinstance(aspect, QName): # dimension aspect concept = modelXbrl.qnameConcepts.get(aspect) if concept is None or not concept.isDimensionItem: modelXbrl.error("xbrlte:invalidDimensionQNameOnAspectNode", _("Aspect node %(xlinkLabel)s dimensional aspect %(dimension)s is not a dimension"), modelObject=(modelTable,definitionNode), xlinkLabel=definitionNode.xlinkLabel, dimension=aspect) if not definitionNodeHasChild: if (definitionNode.namespaceURI in ("http://www.eurofiling.info/2010/rendering", "http://xbrl.org/2011/table") and not hasCoveredAspect): modelXbrl.error("xbrlte:aspectValueNotDefinedByOrdinate", _("%(definitionNode)s %(xlinkLabel)s does not define an aspect"), modelObject=(modelTable,definitionNode), xlinkLabel=definitionNode.xlinkLabel, definitionNode=definitionNode.localName) if (isinstance(definitionNode, ModelClosedDefinitionNode) and definitionNode.isAbstract): modelXbrl.error("xbrlte:abstractRuleNodeNoChildren", _("Abstract %(definitionNode)s %(xlinkLabel)s has no children"), modelObject=(modelTable,definitionNode), xlinkLabel=definitionNode.xlinkLabel, definitionNode=definitionNode.localName) return hasCoveredAspect
def doObject(self, fObj, fromRel, visited): if fObj is None: return if isinstance(fObj, ModelAssertionSet): for modelRel in self.modelXbrl.relationshipSet( XbrlConst.assertionSet).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, visited) elif isinstance( fObj, (ModelValueAssertion, ModelExistenceAssertion, ModelFormula)): for arcrole in (XbrlConst.elementLabel, XbrlConst.assertionSatisfiedMessage, XbrlConst.assertionUnsatisfiedMessage, XbrlConst.assertionUnsatisfiedSeverity): for modelRel in self.modelXbrl.relationshipSet( arcrole).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, visited) if isinstance(fObj, ModelFormula): self.checkProg(fObj, "value", "valueProg") aspectProgs = getattr(fObj, "aspectProgs", {}) for aspect, prog in aspectProgs.items(): self.checkProg(fObj, aspectStr(aspect), prog) for arcrole in (XbrlConst.variableSetFilter, XbrlConst.variableSet, XbrlConst.variableSetPrecondition): for modelRel in self.modelXbrl.relationshipSet( arcrole).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, visited) if isinstance(fObj, (ModelValueAssertion, ModelExistenceAssertion)): self.checkProg(fObj, "test", "testProg") elif isinstance(fObj, ModelConsistencyAssertion): if fObj.hasProportionalAcceptanceRadius: self.checkProg(fObj, "proportionalAcceptanceRadius", "radiusProg") elif fObj.hasProportionalAcceptanceRadius: self.checkProg(fObj, "absoluteAcceptanceRadius", "radiusProg") for arcrole in (XbrlConst.elementLabel, XbrlConst.assertionSatisfiedMessage, XbrlConst.assertionUnsatisfiedMessage): for modelRel in self.modelXbrl.relationshipSet( arcrole).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, visited) for modelRel in self.modelXbrl.relationshipSet( XbrlConst.consistencyAssertionFormula).fromModelObject( fObj): self.doObject(modelRel.toModelObject, modelRel, visited) elif isinstance(fObj, ModelFactVariable) and fromRel is not None: self.checkProg(fObj, "fallbackValue", "fallbackValueProg") for modelRel in self.modelXbrl.relationshipSet( XbrlConst.variableFilter).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, visited) elif isinstance(fObj, ModelGeneralVariable) and fromRel is not None: self.checkProg(fObj, "select", "selectProg") elif isinstance(fObj, ModelParameter): self.checkProg(fObj, "select", "selectProg") elif isinstance(fObj, ModelFilter): if isinstance(fObj, ModelConceptName): for i, prog in enumerate( getattr(fObj, "qnameExpressionProgs", ())): self.checkProg(fObj, "qnameExpression" + str(i + 1), prog) elif isinstance(fObj, ModelExplicitDimension): for i, memberProg in enumerate(getattr(fObj, "memberProgs", ())): if memberProg.qnameExprProg: self.checkProg(fObj, "member{}qnameExpression".format(i + 1), memberProg.qnameExprProg) elif isinstance( fObj, ModelTypedDimension ): # this is a ModelTestFilter not same as genera/unit/period self.checkProg(fObj, "qnameExpression", "dimQnameExpressionProg") elif isinstance(fObj, ModelTestFilter): self.checkProg(fObj, "test", "testProg") elif isinstance(fObj, ModelSingleMeasure): self.checkProg(fObj, "qnameExpression", "qnameExpressionProg") elif isinstance(fObj, ModelEntitySpecificIdentifier): self.checkProg(fObj, "scheme", "schemeProg") self.checkProg(fObj, "value", "valueProg") elif isinstance(fObj, ModelEntityScheme): self.checkProg(fObj, "scheme", "schemeProg") elif isinstance(fObj, (ModelAncestorFilter, ModelParentFilter)): self.checkProg(fObj, "qnameExpression", "qnameExpressionProg") elif isinstance(fObj, ModelAspectCover): for mode in ("include", "exclude"): for i, dimProg in enumerate( getattr(fObj, "{}dDimQnameProgs", ())): self.checkProg( fObj, "{}Dimension{}QnameExpression".format(mode, i + 1), dimProg) elif isinstance(fObj, ModelConceptRelation): self.checkProg(fObj, "qnameExpression", "sourceQnameExpressionProg") self.checkProg(fObj, "linkroleExpression", "linkroleQnameExpressionProg") self.checkProg(fObj, "linknameExpression", "linknameQnameExpressionProg") self.checkProg(fObj, "arcroleExpression", "arcroleQnameExpressionProg") self.checkProg(fObj, "arcnameExpression", "arcnameQnameExpressionProg") self.checkProg(fObj, "test", "testExpressionProg") elif isinstance(fObj, ModelMessage): if isinstance(fObj, ModelConceptName): for i, prog in enumerate(getattr(fObj, "expressionProgs", ())): self.checkProg(fObj, "expression" + str(i + 1), prog) elif isinstance(fObj, ModelCustomFunctionImplementation): self.checkProg(fObj, "output", "outputProg") for i, prog in enumerate(getattr(fObj, "stepProgs", ())): self.checkProg(fObj, "step" + str(i + 1), prog)
def filterFacts(self, facts): modelXbrl = self.sCtx.modelXbrl # process with bindings and this node for i, aspectAxis in enumerate(self.aspectAxisTuples): aspect, hsAxis = aspectAxis # value is an astHyperspaceAxis if hsAxis.restriction: restriction = evaluate(hsAxis.restriction, self.sCtx, value=True) if aspect == Aspect.CONCEPT: aspectQualifiedFacts = [modelXbrl.factsByQname[qn] for qn in restriction if isinstance(qn, QName)] facts = facts & set.union(*aspectQualifiedFacts) if aspectQualifiedFacts else set() elif aspect == Aspect.PERIOD: facts = set(f for f in facts if isPeriodEqualTo(f, restriction)) elif aspect == Aspect.ENTITY_IDENTIFIER: facts = set(f for f in facts if isEntityIdentifierEqualTo(f, restriction)) elif isinstance(aspect, QName): if self.sCtx.dimensionIsExplicit.get(aspect): # explicit dim facts (value None will match the default member) aspectQualifiedFacts = [] for qn in restriction: if self.isBalancingBinding: # complement dimension for aggregation balancing binding if isinstance(qn, QName) or qn is NONDEFAULT: qn = DEFAULT else: qn = NONDEFAULT if qn is NONE: qn = DEFAULT elif not (isinstance(qn, QName) or qn is DEFAULT or qn is NONDEFAULT): continue aspectQualifiedFacts.append(modelXbrl.factsByDimMemQname(aspect, qn)) facts = facts & set.union(*aspectQualifiedFacts) if aspectQualifiedFacts else set() else: facts = facts & set(fact for fact in facts for typedDimValue in hsAxis.restriction if typedDimTest(aspect, typedDimValue, fact)) if hsAxis.whereExpr and facts: # process where against facts passing restriction whereMatchedFacts = set() asVars = set() for fact in facts: for asAspectAxis in self.aspectAxisTuples[0:i+1]: asAspect, asHsAxis = asAspectAxis if asHsAxis.asVariableName: self.sCtx.localVariables[asHsAxis.asVariableName] = factAspectValue(fact, asAspect) asVars.add(asHsAxis.asVariableName) self.sCtx.localVariables["item"] = fact if evaluate(hsAxis.whereExpr, self.sCtx) ^ self.isBalancingBinding: whereMatchedFacts.add(fact) del self.sCtx.localVariables["item"] for asVar in asVars: del self.sCtx.localVariables[asVar] facts = whereMatchedFacts if self.sCtx.formulaOptions.traceVariableFilterWinnowing: self.sCtx.modelXbrl.info("sphinx:trace", _("Hyperspace %(variable)s: %(filter)s filter passes %(factCount)s facts"), sourceFileLine=self.node.sourceFileLine, variable=str(self.node), filter=aspectStr(aspect), factCount=len(facts)) if self.node.isClosed: # winnow out non-qualified dimension breakdowns facts = facts - set(fact for fact in facts if fact.dimAspects - self.aspectsQualified ) if self.sCtx.formulaOptions.traceVariableFilterWinnowing: self.sCtx.modelXbrl.info("sphinx:trace", _("Hyperspace %(variable)s: closed selection filter passes %(factCount)s facts"), sourceFileLine=self.node.sourceFileLine, variable=str(self.node), factCount=len(facts)) return facts
def filterFacts(self, facts): modelXbrl = self.sCtx.modelXbrl # process with bindings and this node for i, aspectAxis in enumerate(self.aspectAxisTuples): aspect, hsAxis = aspectAxis # value is an astHyperspaceAxis if hsAxis.restriction: restriction = evaluate(hsAxis.restriction, self.sCtx, value=True) if aspect == Aspect.CONCEPT: aspectQualifiedFacts = [ modelXbrl.factsByQname[qn] for qn in restriction if isinstance(qn, QName) ] facts = facts & set.union( *aspectQualifiedFacts ) if aspectQualifiedFacts else set() elif aspect == Aspect.PERIOD: facts = set(f for f in facts if isPeriodEqualTo(f, restriction)) elif aspect == Aspect.ENTITY_IDENTIFIER: facts = set(f for f in facts if isEntityIdentifierEqualTo(f, restriction)) elif isinstance(aspect, QName): if self.sCtx.dimensionIsExplicit.get(aspect): # explicit dim facts (value None will match the default member) aspectQualifiedFacts = [] for qn in restriction: if self.isBalancingBinding: # complement dimension for aggregation balancing binding if isinstance(qn, QName) or qn is NONDEFAULT: qn = DEFAULT else: qn = NONDEFAULT if qn is NONE: qn = DEFAULT elif not (isinstance(qn, QName) or qn is DEFAULT or qn is NONDEFAULT): continue aspectQualifiedFacts.append( modelXbrl.factsByDimMemQname(aspect, qn)) facts = facts & set.union( *aspectQualifiedFacts ) if aspectQualifiedFacts else set() else: facts = facts & set( fact for fact in facts for typedDimValue in hsAxis.restriction if typedDimTest(aspect, typedDimValue, fact)) if hsAxis.whereExpr and facts: # process where against facts passing restriction whereMatchedFacts = set() asVars = set() for fact in facts: for asAspectAxis in self.aspectAxisTuples[0:i + 1]: asAspect, asHsAxis = asAspectAxis if asHsAxis.asVariableName: self.sCtx.localVariables[ asHsAxis.asVariableName] = factAspectValue( fact, asAspect) asVars.add(asHsAxis.asVariableName) self.sCtx.localVariables["item"] = fact if evaluate(hsAxis.whereExpr, self.sCtx) ^ self.isBalancingBinding: whereMatchedFacts.add(fact) del self.sCtx.localVariables["item"] for asVar in asVars: del self.sCtx.localVariables[asVar] facts = whereMatchedFacts if self.sCtx.formulaOptions.traceVariableFilterWinnowing: self.sCtx.modelXbrl.info( "sphinx:trace", _("Hyperspace %(variable)s: %(filter)s filter passes %(factCount)s facts" ), sourceFileLine=self.node.sourceFileLine, variable=str(self.node), filter=aspectStr(aspect), factCount=len(facts)) if self.node.isClosed: # winnow out non-qualified dimension breakdowns facts = facts - set(fact for fact in facts if fact.dimAspects - self.aspectsQualified) if self.sCtx.formulaOptions.traceVariableFilterWinnowing: self.sCtx.modelXbrl.info( "sphinx:trace", _("Hyperspace %(variable)s: closed selection filter passes %(factCount)s facts" ), sourceFileLine=self.node.sourceFileLine, variable=str(self.node), factCount=len(facts)) return facts
def view(self, viewTblELR=None): if viewTblELR is not None: tblELRs = (viewTblELR,) else: tblELRs = self.modelXbrl.relationshipSet("Table-rendering").linkRoleUris if self.type == XML: self.tblElt.append(etree.Comment("Entry point file: {0}".format(self.modelXbrl.modelDocument.basename))) for tblELR in tblELRs: self.zOrdinateChoices = {} for discriminator in range(1, 65535): tblAxisRelSet, xTopStructuralNode, yTopStructuralNode, zTopStructuralNode = resolveAxesStructure(self, tblELR) self.zStrNodesWithChoices = [] if tblAxisRelSet and self.tblElt is not None: tableLabel = (self.modelTable.genLabel(lang=self.lang, strip=True) or # use table label, if any self.roledefinition) if self.type == HTML: # table on each Z # each Z is a separate table in the outer table zTableRow = etree.SubElement(self.tblElt, "{http://www.w3.org/1999/xhtml}tr") zRowCell = etree.SubElement(zTableRow, "{http://www.w3.org/1999/xhtml}td") zCellTable = etree.SubElement(zRowCell, "{http://www.w3.org/1999/xhtml}table", attrib={"border":"1", "cellspacing":"0", "cellpadding":"4", "style":"font-size:8pt;"}) self.rowElts = [etree.SubElement(zCellTable, "{http://www.w3.org/1999/xhtml}tr") for r in range(self.dataFirstRow + self.dataRows - 1)] etree.SubElement(self.rowElts[0], "{http://www.w3.org/1999/xhtml}th", attrib={"class":"tableHdr", "style":"max-width:100em;", "colspan": str(self.dataFirstCol - 1), "rowspan": str(self.dataFirstRow - 1)} ).text = tableLabel elif self.type == XML: self.structuralNodeModelElements = [] if discriminator == 1: tableSetElt = etree.SubElement(self.tblElt, tableModelQName("tableSet")) tableSetElt.append(etree.Comment("TableSet linkbase file: {0}, line {1}".format(self.modelTable.modelDocument.basename, self.modelTable.sourceline))) tableSetElt.append(etree.Comment("TableSet namespace: {0}".format(self.modelTable.namespaceURI))) tableSetElt.append(etree.Comment("TableSet linkrole: {0}".format(tblELR))) self.zHdrsElt = etree.SubElement(tableSetElt, tableModelQName("headers")) zAspects = defaultdict(set) self.zAxis(1, zTopStructuralNode, zAspects, True) tableElt = etree.SubElement(tableSetElt, tableModelQName("table"), attrib={"label": tableLabel}) hdrsElts = dict((disposition, etree.SubElement(tableElt, tableModelQName("headers"), attrib={"disposition": disposition})) for disposition in ("y", "x")) self.zHdrsElt = hdrsElts["y"] # z-comments go before y subelement of tableElt # new y,x cells on each Z combination if yTopStructuralNode.childStructuralNodes: # no row header element if no rows self.rowHdrElts = [etree.SubElement(hdrsElts["y"], tableModelQName("header")) for i in range(self.rowHdrCols - 1 + len(self.rowHdrNonStdRoles))] # self.rowHdrDocCol + self.rowHdrCodeCol)] else: hdrsElts["y"].append(etree.Comment("no rows in this table")) if xTopStructuralNode.childStructuralNodes: # no col header element if no cols self.colHdrElts = [etree.SubElement(hdrsElts["x"], tableModelQName("header")) for i in range(self.colHdrRows - 1 + len(self.colHdrNonStdRoles))] # self.colHdrDocRow + self.colHdrCodeRow)] else: hdrsElts["x"].append(etree.Comment("no columns in this table")) self.zCells = etree.SubElement(tableElt, tableModelQName("cells"), attrib={"disposition": "z"}) self.yCells = etree.SubElement(self.zCells, tableModelQName("cells"), attrib={"disposition": "y"}) ''' move into body cells, for entry row-by-row self.xCells = etree.SubElement(self.yCells, tableModelQName("cells"), attrib={"disposition": "x"}) ''' # rows/cols only on firstTime for infoset XML, but on each time for xhtml zAspects = defaultdict(set) self.zAxis(1, zTopStructuralNode, zAspects, False) xStructuralNodes = [] if self.type == HTML or (xTopStructuralNode.childStructuralNodes): self.xAxis(self.dataFirstCol, self.colHdrTopRow, self.colHdrTopRow + self.colHdrRows - 1, xTopStructuralNode, xStructuralNodes, self.xAxisChildrenFirst.get(), True, True) if self.type == HTML: # table/tr goes by row self.yAxisByRow(1, self.dataFirstRow, yTopStructuralNode, self.yAxisChildrenFirst.get(), True, True) elif self.type == XML: # infoset goes by col of row header if yTopStructuralNode.childStructuralNodes: # no row header element if no rows self.yAxisByCol(1, self.dataFirstRow, yTopStructuralNode, self.yAxisChildrenFirst.get(), True, True) for structuralNode,modelElt in self.structuralNodeModelElements: # must do after elements are all arragned modelElt.addprevious(etree.Comment("{0}: label {1}, file {2}, line {3}" .format(structuralNode._definitionNode.localName, structuralNode._definitionNode.xlinkLabel, structuralNode._definitionNode.modelDocument.basename, structuralNode._definitionNode.sourceline))) if structuralNode._definitionNode.get('value'): modelElt.addprevious(etree.Comment(" @value {0}".format(structuralNode._definitionNode.get('value')))) for aspect in sorted(structuralNode.aspectsCovered(), key=lambda a: aspectStr(a)): if structuralNode.hasAspect(aspect) and aspect != Aspect.DIMENSIONS: aspectValue = structuralNode.aspectValue(aspect) if aspectValue is None: aspectValue = "(bound dynamically)" modelElt.addprevious(etree.Comment(" aspect {0}: {1}".format(aspectStr(aspect), aspectValue))) for varName, varValue in structuralNode.variables.items(): modelElt.addprevious(etree.Comment(" variable ${0}: {1}".format(varName, varValue))) self.bodyCells(self.dataFirstRow, yTopStructuralNode, xStructuralNodes, zAspects, self.yAxisChildrenFirst.get()) # find next choice structural node moreDiscriminators = False for zStrNodeWithChoices in self.zStrNodesWithChoices: currentIndex = zStrNodeWithChoices.choiceNodeIndex + 1 if currentIndex < len(zStrNodeWithChoices.choiceStructuralNodes): zStrNodeWithChoices.choiceNodeIndex = currentIndex self.zOrdinateChoices[zStrNodeWithChoices._definitionNode] = currentIndex moreDiscriminators = True break else: zStrNodeWithChoices.choiceNodeIndex = 0 self.zOrdinateChoices[zStrNodeWithChoices._definitionNode] = 0 # continue incrementing next outermore z choices index if not moreDiscriminators: break
def yAxisByCol(self, leftCol, row, yParentStructuralNode, childrenFirst, renderNow, atTop): if yParentStructuralNode is not None: nestedBottomRow = row for yStructuralNode in yParentStructuralNode.childStructuralNodes: nestRow, nextRow = self.yAxisByCol(leftCol + 1, row, yStructuralNode, # nested items before totals childrenFirst, childrenFirst, False) isAbstract = (yStructuralNode.isAbstract or (yStructuralNode.childStructuralNodes and not isinstance(yStructuralNode.definitionNode, (ModelClosedDefinitionNode, ModelEuAxisCoord)))) isNonAbstract = not isAbstract label = yStructuralNode.header(lang=self.lang, returnGenLabel=isinstance(yStructuralNode.definitionNode, (ModelClosedDefinitionNode, ModelEuAxisCoord))) topRow = row if childrenFirst and isNonAbstract: row = nextRow #print ( "thisCol {0} leftCol {1} rightCol {2} topRow{3} renderNow {4} label {5}".format(thisCol, leftCol, rightCol, topRow, renderNow, label)) if renderNow: rowspan= nestRow - row + 1 cellElt = etree.Element(tableModelQName("cell"), attrib={"span": str(rowspan)} if rowspan > 1 else None) elt = etree.SubElement(cellElt, tableModelQName("label")) elt.text = label self.rowHdrElts[leftCol - 1].append(cellElt) self.structuralNodeModelElements.append((yStructuralNode, cellElt)) for aspect in sorted(yStructuralNode.aspectsCovered(), key=lambda a: aspectStr(a)): if yStructuralNode.hasAspect(aspect) and aspect != Aspect.DIMENSIONS: aspectValue = yStructuralNode.aspectValue(aspect) if aspectValue is None: aspectValue = "(bound dynamically)" elt = etree.SubElement(cellElt, tableModelQName("constraint")) etree.SubElement(elt, tableModelQName("aspect") ).text = aspectStr(aspect) etree.SubElement(elt, tableModelQName("value") ).text = addQnameValue(self.xmlDoc, aspectValue) for rollUpCol in range(leftCol, self.rowHdrCols - 1): rollUpElt = etree.Element(tableModelQName("cell"), attrib={"rollup":"true"}) self.rowHdrElts[rollUpCol].append(rollUpElt) if isNonAbstract: cellElt = etree.Element(tableModelQName("cell"), attrib={"span": str(rowspan)} if rowspan > 1 else None) for i, role in enumerate(self.rowHdrNonStdRoles): labelElt = etree.SubElement(cellElt, tableModelQName("label"), attrib={"role":role, "lang":self.lang}) labelElt.text = yStructuralNode.header(role=role, lang=self.lang) self.rowHdrElts[self.rowHdrCols - 1 + i].append(cellElt) for aspect in sorted(yStructuralNode.aspectsCovered(), key=lambda a: aspectStr(a)): if yStructuralNode.hasAspect(aspect) and aspect != Aspect.DIMENSIONS: aspectValue = yStructuralNode.aspectValue(aspect) if aspectValue is None: aspectValue = "(bound dynamically)" elt = etree.SubElement(cellElt, tableModelQName("constraint")) etree.SubElement(elt, tableModelQName("aspect") ).text = aspectStr(aspect) etree.SubElement(elt, tableModelQName("value") ).text = addQnameValue(self.xmlDoc, aspectValue) ''' if self.rowHdrDocCol: labelElt = etree.SubElement(cellElt, tableModelQName("label"), attrib={"span": str(rowspan)} if rowspan > 1 else None) elt.text = yStructuralNode.header(role="http://www.xbrl.org/2008/role/documentation", lang=self.lang) self.rowHdrElts[self.rowHdrCols - 1].append(elt) if self.rowHdrCodeCol: elt = etree.Element(tableModelQName("label"), attrib={"span": str(rowspan)} if rowspan > 1 else None) elt.text = yStructuralNode.header(role="http://www.eurofiling.info/role/2010/coordinate-code", lang=self.lang) self.rowHdrElts[self.rowHdrCols - 1 + self.rowHdrDocCol].append(elt) ''' if isNonAbstract: row += 1 elif childrenFirst: row = nextRow if nestRow > nestedBottomRow: nestedBottomRow = nestRow + (isNonAbstract and not childrenFirst) if row > nestedBottomRow: nestedBottomRow = row #if renderNow and not childrenFirst: # dummy, row = self.yAxis(leftCol + 1, row, yStructuralNode, childrenFirst, True, False) # render on this pass if not childrenFirst: dummy, row = self.yAxisByCol(leftCol + 1, row, yStructuralNode, childrenFirst, renderNow, False) # render on this pass return (nestedBottomRow, row)
def xAxis(self, leftCol, topRow, rowBelow, xParentStructuralNode, xStructuralNodes, childrenFirst, renderNow, atTop): if xParentStructuralNode is not None: parentRow = rowBelow noDescendants = True rightCol = leftCol widthToSpanParent = 0 sideBorder = not xStructuralNodes for xStructuralNode in xParentStructuralNode.childStructuralNodes: noDescendants = False rightCol, row, width, leafNode = self.xAxis(leftCol, topRow + 1, rowBelow, xStructuralNode, xStructuralNodes, # nested items before totals childrenFirst, childrenFirst, False) if row - 1 < parentRow: parentRow = row - 1 #if not leafNode: # rightCol -= 1 nonAbstract = not xStructuralNode.isAbstract if nonAbstract: width += 100 # width for this label widthToSpanParent += width label = xStructuralNode.header(lang=self.lang, returnGenLabel=isinstance(xStructuralNode.definitionNode, (ModelClosedDefinitionNode, ModelEuAxisCoord))) if childrenFirst: thisCol = rightCol else: thisCol = leftCol #print ( "thisCol {0} leftCol {1} rightCol {2} topRow{3} renderNow {4} label {5}".format(thisCol, leftCol, rightCol, topRow, renderNow, label)) if renderNow: columnspan = rightCol - leftCol + (1 if nonAbstract else 0) if self.type == HTML: if rightCol == self.dataFirstCol + self.dataCols - 1: edgeBorder = "border-right:.5pt solid windowtext;" else: edgeBorder = "" attrib = {"class":"xAxisHdr", "style":"text-align:center;max-width:{0}pt;{1}".format(width,edgeBorder)} if columnspan > 1: attrib["colspan"] = str(columnspan) if leafNode and row > topRow: attrib["rowspan"] = str(row - topRow + 1) elt = etree.Element("{http://www.w3.org/1999/xhtml}th", attrib=attrib) self.rowElts[topRow-1].insert(leftCol,elt) elif self.type == XML: cellElt = etree.Element(tableModelQName("cell"), attrib={"span": str(columnspan)} if columnspan > 1 else None) self.colHdrElts[topRow - self.colHdrTopRow].insert(leftCol,cellElt) self.structuralNodeModelElements.append((xStructuralNode, cellElt)) elt = etree.SubElement(cellElt, tableModelQName("label")) if nonAbstract or (leafNode and row > topRow): for rollUpCol in range(topRow - self.colHdrTopRow + 1, self.colHdrRows - 1): rollUpElt = etree.Element(tableModelQName("label"), attrib={"rollup":"true"}) if childrenFirst: self.colHdrElts[rollUpCol].append(rollUpElt) else: self.colHdrElts[rollUpCol].insert(leftCol,rollUpElt) for i, role in enumerate(self.colHdrNonStdRoles): etree.SubElement(cellElt, tableModelQName("label"), attrib={"role": role, "lang": self.lang} ).text = xStructuralNode.header( role=role, lang=self.lang) for aspect in sorted(xStructuralNode.aspectsCovered(), key=lambda a: aspectStr(a)): if xStructuralNode.hasAspect(aspect) and aspect != Aspect.DIMENSIONS: aspectValue = xStructuralNode.aspectValue(aspect) if aspectValue is None: aspectValue = "(bound dynamically)" aspElt = etree.SubElement(cellElt, tableModelQName("constraint")) etree.SubElement(aspElt, tableModelQName("aspect") ).text = aspectStr(aspect) etree.SubElement(aspElt, tableModelQName("value") ).text = addQnameValue(self.xmlDoc, aspectValue) elt.text = label or "\u00A0" #produces if nonAbstract: if columnspan > 1 and rowBelow > topRow: # add spanned left leg portion one row down if self.type == HTML: attrib= {"class":"xAxisSpanLeg", "rowspan": str(rowBelow - row)} if edgeBorder: attrib["style"] = edgeBorder elt = etree.Element("{http://www.w3.org/1999/xhtml}th", attrib=attrib) elt.text = "\u00A0" if childrenFirst: self.rowElts[topRow].append(elt) else: self.rowElts[topRow].insert(leftCol,elt) if self.type == HTML: for i, role in enumerate(self.colHdrNonStdRoles): elt = etree.Element("{http://www.w3.org/1999/xhtml}th", attrib={"class":"xAxisHdr", "style":"text-align:center;max-width:100pt;{0}".format(edgeBorder)}) self.rowElts[self.dataFirstRow - 1 - len(self.colHdrNonStdRoles) + i].insert(thisCol,elt) elt.text = xStructuralNode.header(role=role, lang=self.lang) or "\u00A0" ''' if self.colHdrDocRow: doc = xStructuralNode.header(role="http://www.xbrl.org/2008/role/documentation", lang=self.lang) if self.type == HTML: elt = etree.Element("{http://www.w3.org/1999/xhtml}th", attrib={"class":"xAxisHdr", "style":"text-align:center;max-width:100pt;{0}".format(edgeBorder)}) self.rowElts[self.dataFirstRow - 2 - self.rowHdrCodeCol].insert(thisCol,elt) elif self.type == XML: elt = etree.Element(tableModelQName("label")) self.colHdrElts[self.colHdrRows - 1].insert(thisCol,elt) elt.text = doc or "\u00A0" if self.colHdrCodeRow: code = xStructuralNode.header(role="http://www.eurofiling.info/role/2010/coordinate-code") if self.type == HTML: elt = etree.Element("{http://www.w3.org/1999/xhtml}th", attrib={"class":"xAxisHdr", "style":"text-align:center;max-width:100pt;{0}".format(edgeBorder)}) self.rowElts[self.dataFirstRow - 2].insert(thisCol,elt) elif self.type == XML: elt = etree.Element(tableModelQName("label")) self.colHdrElts[self.colHdrRows - 1 + self.colHdrDocRow].insert(thisCol,elt) elt.text = code or "\u00A0" ''' xStructuralNodes.append(xStructuralNode) if nonAbstract: rightCol += 1 if renderNow and not childrenFirst: self.xAxis(leftCol + (1 if nonAbstract else 0), topRow + 1, rowBelow, xStructuralNode, xStructuralNodes, childrenFirst, True, False) # render on this pass leftCol = rightCol return (rightCol, parentRow, widthToSpanParent, noDescendants)