Example #1
0
def nodes_correspond(xc, p, args):
    if len(args) != 2: raise XPathContext.FunctionNumArgs()
    node1 = nodeArg(xc, args, 0, "node()?", missingArgFallback=(), emptyFallback=())
    node2 = nodeArg(xc, args, 1, "node()?", missingArgFallback=(), emptyFallback=())
    if node1 == ():
        if node2 == (): return True
        return False
    if node2 == (): return False
    return XbrlUtil.nodesCorrespond(xc.modelXbrl, node1, node2, xc.modelXbrl)
Example #2
0
 def isEqualTo(self, other, equalMode=XbrlUtil.XPATH_EQ):
     if isinstance(other, ModelValue.QName):
         return self.isExplicit and self.memberQname == other
     elif other is None:
         return False
     elif self.isExplicit:
         return self.memberQname == other.memberQname
     else:
         return XbrlUtil.nodesCorrespond(self.modelXbrl, self.typedMember, other.typedMember, 
                                         equalMode=equalMode, excludeIDs=XbrlUtil.NO_IDs_EXCLUDED)
Example #3
0
 def isEqualTo(self, other, equalMode=XbrlUtil.XPATH_EQ):
     """(bool) -- True if explicit member QNames equal or typed member nodes correspond, given equalMode (s-equal, s-equal2, or xpath-equal for formula)
     
     :param equalMode: XbrlUtil.S_EQUAL (ordinary S-equality from 2.1 spec), XbrlUtil.S_EQUAL2 (XDT definition of equality, adding QName comparisions), or XbrlUtil.XPATH_EQ (XPath EQ on all types)
     """
     if other is None:
         return False
     if self.isExplicit: # other is either ModelDimensionValue or the QName value of explicit dimension
         return self.memberQname == (other.memberQname if isinstance(other, (ModelDimensionValue,DimValuePrototype)) else other)
     else: # typed dimension compared to another ModelDimensionValue or other is the value nodes
         return XbrlUtil.nodesCorrespond(self.modelXbrl, self.typedMember, 
                                         other.typedMember if isinstance(other, (ModelDimensionValue,DimValuePrototype)) else other, 
                                         equalMode=equalMode, excludeIDs=XbrlUtil.NO_IDs_EXCLUDED)
Example #4
0
 def isEqualTo(self, other, equalMode=XbrlUtil.XPATH_EQ):
     if isinstance(other, ModelValue.QName):
         return self.isExplicit and self.memberQname == other
     elif other is None:
         return False
     elif self.isExplicit:
         return self.memberQname == other.memberQname
     else:
         return XbrlUtil.nodesCorrespond(
             self.modelXbrl,
             self.typedMember,
             other.typedMember,
             equalMode=equalMode,
             excludeIDs=XbrlUtil.NO_IDs_EXCLUDED)
Example #5
0
def nodes_correspond(xc, p, args):
    if len(args) != 2: raise XPathContext.FunctionNumArgs()
    node1 = nodeArg(xc,
                    args,
                    0,
                    "node()?",
                    missingArgFallback=(),
                    emptyFallback=())
    node2 = nodeArg(xc,
                    args,
                    1,
                    "node()?",
                    missingArgFallback=(),
                    emptyFallback=())
    if node1 == ():
        if node2 == (): return True
        return False
    if node2 == (): return False
    return XbrlUtil.nodesCorrespond(xc.modelXbrl, node1, node2, xc.modelXbrl)
Example #6
0
def deep_equal(xc, p, contextItem, args):
    if len(args) != 2: raise XPathContext.FunctionNumArgs()
    return XbrlUtil.nodesCorrespond(xc.modelXbrl, args[0], args[1])
Example #7
0
def aspectMatches(fact1, fact2, aspects):
    matches = True
    for aspect in (aspects if hasattr(aspects, '__iter__') else (aspects, )):
        if aspect == Aspect.LOCATION:
            if (fact1.modelXbrl == fact2.modelXbrl
                    and  # test deemed true for multi-instance comparisons
                    fact1.element.parentNode != fact2.element.parentNode):
                matches = False
        elif aspect == Aspect.CONCEPT:
            if fact1.concept.qname != fact2.concept.qname: matches = False
        elif fact1.isTuple or fact2.isTuple:
            return True  # only match the aspects both facts have
        elif aspect == Aspect.PERIOD:
            if not fact1.context.isPeriodEqualTo(fact2.context):
                matches = False
        elif aspect == Aspect.ENTITY_IDENTIFIER:
            if not fact1.context.isEntityIdentifierEqualTo(fact2.context):
                matches = False
        elif aspect == Aspect.COMPLETE_SEGMENT:
            if not XbrlUtil.nodesCorrespond(fact1.modelXbrl,
                                            fact1.context.segment,
                                            fact2.context.segment,
                                            dts2=fact2.modelXbrl):
                matches = False
        elif aspect == Aspect.COMPLETE_SCENARIO:
            if not XbrlUtil.nodesCorrespond(fact1.modelXbrl,
                                            fact1.context.scenario,
                                            fact2.context.scenario,
                                            dts2=fact2.modelXbrl):
                matches = False
        elif aspect in (Aspect.NON_XDT_SEGMENT, Aspect.NON_XDT_SCENARIO):
            nXs1 = fact1.context.nonDimValues(aspect)
            nXs2 = fact2.context.nonDimValues(aspect)
            if len(nXs1) != len(nXs2):
                matches = False
            else:
                for i in range(len(nXs1)):
                    if not XbrlUtil.nodesCorrespond(fact1.modelXbrl,
                                                    nXs1[i],
                                                    nXs2[i],
                                                    dts2=fact2.modelXbrl):
                        matches = False
                        break
        elif aspect == Aspect.UNIT:
            u1 = fact1.unit
            u2 = fact2.unit
            if (u1 is None) != (u2 is None):
                matches = False
            elif u1 and u2 and u1.measures != u2.measures:
                matches = False
        elif aspect == Aspect.DIMENSIONS:
            ''' (no implicit filtering on ALL dimensions for now)
            dimQnames1 = fact1.context.dimAspects
            dimQnames2 = fact2.context.dimAspects
            if len(dimQnames1 ^ dimQnames2):  # dims not in both
                matches = False
            else:
                for dimQname1 in dimQnames1:
                    if dimQname1 not in dimQnames2 or \
                       not aspectMatches(fact1, fact2, dimQname1):
                        matches = False
                        break
            '''
        elif isinstance(aspect, QName):
            from arelle.ModelObject import ModelDimensionValue
            dimValue1 = fact1.context.dimValue(aspect)
            dimValue2 = fact2.context.dimValue(aspect)
            if isinstance(dimValue1, ModelDimensionValue):
                if dimValue1.isExplicit:
                    if isinstance(dimValue2, QName):
                        if dimValue1.memberQname != dimValue2:
                            matches = False
                    elif isinstance(dimValue2, ModelDimensionValue):
                        if dimValue2.isTyped:
                            matches = False
                        elif dimValue1.memberQname != dimValue2.memberQname:
                            matches = False
                elif dimValue1.isTyped:
                    if isinstance(dimValue2, QName):
                        matches = False
                    elif isinstance(dimValue2, ModelDimensionValue):
                        if dimValue2.isExplicit:
                            matches = False
                        elif not XbrlUtil.nodesCorrespond(
                                fact1.modelXbrl,
                                dimValue1.typedMember,
                                dimValue2.typedMember,
                                dts2=fact2.modelXbrl):
                            matches = False
            elif isinstance(dimValue1, QName):
                if isinstance(dimValue2, QName):
                    if dimValue1 != dimValue2:
                        matches = False
                elif isinstance(dimValue2, ModelDimensionValue):
                    if dimValue2.isTyped:
                        matches = False
                    elif dimValue1 != dimValue2.memberQname:
                        matches = False
            elif dimValue1 is None:
                if dimValue2:
                    matches = False
        if not matches:
            break
    return matches
Example #8
0
def aspectMatches(fact1, fact2, aspects):
    matches = True
    for aspect in (aspects if hasattr(aspects,'__iter__') else (aspects,)):
        if aspect == Aspect.LOCATION:
            if (fact1.modelXbrl == fact2.modelXbrl and # test deemed true for multi-instance comparisons
                fact1.element.parentNode != fact2.element.parentNode): matches = False
        elif aspect == Aspect.CONCEPT:
            if fact1.concept.qname != fact2.concept.qname: matches = False
        elif fact1.isTuple or fact2.isTuple:
            return True # only match the aspects both facts have 
        elif aspect == Aspect.PERIOD:
            if not fact1.context.isPeriodEqualTo(fact2.context): matches = False
        elif aspect == Aspect.ENTITY_IDENTIFIER:
            if not fact1.context.isEntityIdentifierEqualTo(fact2.context): matches = False
        elif aspect == Aspect.COMPLETE_SEGMENT:
            if not XbrlUtil.nodesCorrespond(fact1.modelXbrl, fact1.context.segment, fact2.context.segment, dts2=fact2.modelXbrl): 
                matches = False
        elif aspect == Aspect.COMPLETE_SCENARIO:
            if not XbrlUtil.nodesCorrespond(fact1.modelXbrl, fact1.context.scenario, fact2.context.scenario, dts2=fact2.modelXbrl): 
                matches = False
        elif aspect in (Aspect.NON_XDT_SEGMENT, Aspect.NON_XDT_SCENARIO):
            nXs1 = fact1.context.nonDimValues(aspect)
            nXs2 = fact2.context.nonDimValues(aspect)
            if len(nXs1) != len(nXs2):
                matches = False
            else:
                for i in range(len(nXs1)):
                    if not XbrlUtil.nodesCorrespond(fact1.modelXbrl, nXs1[i], nXs2[i], dts2=fact2.modelXbrl): 
                        matches = False
                        break
        elif aspect == Aspect.UNIT:
            u1 = fact1.unit
            u2 = fact2.unit
            if (u1 is None) != (u2 is None):
                matches = False
            elif u1 and u2 and u1.measures != u2.measures:
                matches = False
        elif aspect == Aspect.DIMENSIONS:
            ''' (no implicit filtering on ALL dimensions for now)
            dimQnames1 = fact1.context.dimAspects
            dimQnames2 = fact2.context.dimAspects
            if len(dimQnames1 ^ dimQnames2):  # dims not in both
                matches = False
            else:
                for dimQname1 in dimQnames1:
                    if dimQname1 not in dimQnames2 or \
                       not aspectMatches(fact1, fact2, dimQname1):
                        matches = False
                        break
            '''
        elif isinstance(aspect, QName):
            from arelle.ModelObject import ModelDimensionValue
            dimValue1 = fact1.context.dimValue(aspect)
            dimValue2 = fact2.context.dimValue(aspect)
            if isinstance(dimValue1, ModelDimensionValue):
                if dimValue1.isExplicit: 
                    if isinstance(dimValue2, QName):
                        if dimValue1.memberQname != dimValue2:
                            matches = False
                    elif isinstance(dimValue2, ModelDimensionValue):
                        if dimValue2.isTyped:
                            matches = False
                        elif dimValue1.memberQname != dimValue2.memberQname:
                            matches = False 
                elif dimValue1.isTyped:
                    if isinstance(dimValue2, QName):
                        matches = False
                    elif isinstance(dimValue2, ModelDimensionValue):
                        if dimValue2.isExplicit:
                            matches = False
                        elif not XbrlUtil.nodesCorrespond(fact1.modelXbrl, dimValue1.typedMember, dimValue2.typedMember, dts2=fact2.modelXbrl):
                            matches = False
            elif isinstance(dimValue1,QName):
                if isinstance(dimValue2, QName):
                    if dimValue1 != dimValue2:
                        matches = False
                elif isinstance(dimValue2, ModelDimensionValue):
                    if dimValue2.isTyped:
                        matches = False
                    elif dimValue1 != dimValue2.memberQname:
                        matches = False 
            elif dimValue1 is None:
                if dimValue2:
                    matches = False
        if not matches: 
            break
    return matches
Example #9
0
def aspectMatches(xpCtx, fact1, fact2, aspects):
    if fact1 is None or fact2 is None:  # fallback (atomic) never matches any aspect
        return False
    matches = True
    for aspect in (aspects if hasattr(aspects,'__iter__') else (aspects,)):
        if aspect == Aspect.LOCATION:
            if (fact1.modelXbrl == fact2.modelXbrl and # test deemed true for multi-instance comparisons
                fact1.getparent() != fact2.getparent()): matches = False
        elif aspect == Aspect.CONCEPT:
            if fact1.concept.qname != fact2.concept.qname: matches = False
        elif fact1.isTuple or fact2.isTuple:
            return True # only match the aspects both facts have 
        elif aspect == Aspect.PERIOD:
            if not fact1.context.isPeriodEqualTo(fact2.context): matches = False
        elif aspect == Aspect.ENTITY_IDENTIFIER:
            if not fact1.context.isEntityIdentifierEqualTo(fact2.context): matches = False
        elif aspect == Aspect.COMPLETE_SEGMENT:
            if not XbrlUtil.nodesCorrespond(fact1.modelXbrl, fact1.context.segment, fact2.context.segment, dts2=fact2.modelXbrl): 
                matches = False
        elif aspect == Aspect.COMPLETE_SCENARIO:
            if not XbrlUtil.nodesCorrespond(fact1.modelXbrl, fact1.context.scenario, fact2.context.scenario, dts2=fact2.modelXbrl): 
                matches = False
        elif aspect in (Aspect.NON_XDT_SEGMENT, Aspect.NON_XDT_SCENARIO):
            nXs1 = fact1.context.nonDimValues(aspect)
            nXs2 = fact2.context.nonDimValues(aspect)
            if len(nXs1) != len(nXs2):
                matches = False
            else:
                for i in range(len(nXs1)):
                    if not XbrlUtil.nodesCorrespond(fact1.modelXbrl, nXs1[i], nXs2[i], dts2=fact2.modelXbrl): 
                        matches = False
                        break
        elif aspect == Aspect.UNIT:
            u1 = fact1.unit
            u2 = fact2.unit
            if (u1 is None) != (u2 is None):
                matches = False
            elif u1 is not None and u2 is not None and u1.measures != u2.measures:
                matches = False
        elif aspect == Aspect.DIMENSIONS:
            ''' (no implicit filtering on ALL dimensions for now)
            dimQnames1 = fact1.context.dimAspects
            dimQnames2 = fact2.context.dimAspects
            if len(dimQnames1 ^ dimQnames2):  # dims not in both
                matches = False
            else:
                for dimQname1 in dimQnames1:
                    if dimQname1 not in dimQnames2 or \
                       not aspectMatches(fact1, fact2, dimQname1):
                        matches = False
                        break
            '''
        elif isinstance(aspect, QName):
            from arelle.ModelInstanceObject import ModelDimensionValue
            dimValue1 = fact1.context.dimValue(aspect)
            dimValue2 = fact2.context.dimValue(aspect)
            if isinstance(dimValue1, ModelDimensionValue):
                if dimValue1.isExplicit: 
                    if isinstance(dimValue2, QName):
                        if dimValue1.memberQname != dimValue2:
                            matches = False
                    elif isinstance(dimValue2, ModelDimensionValue):
                        if dimValue2.isTyped:
                            matches = False
                        elif dimValue1.memberQname != dimValue2.memberQname:
                            matches = False 
                    elif dimValue2 is None:
                        matches = False
                elif dimValue1.isTyped:
                    if isinstance(dimValue2, QName):
                        matches = False
                    elif isinstance(dimValue2, ModelDimensionValue):
                        if dimValue2.isExplicit:
                            matches = False
                        elif dimValue1.dimension.typedDomainElement in xpCtx.modelXbrl.modelFormulaEqualityDefinitions:
                            equalityDefinition = xpCtx.modelXbrl.modelFormulaEqualityDefinitions[dimValue1.dimension.typedDomainElement]
                            matches = equalityDefinition.evalTest(xpCtx, fact1, fact2)
                        elif not XbrlUtil.nodesCorrespond(fact1.modelXbrl, dimValue1.typedMember, dimValue2.typedMember, dts2=fact2.modelXbrl):
                            matches = False
                    elif dimValue2 is None:
                        matches = False
            elif isinstance(dimValue1,QName): # first dim is default value of an explicit dim
                if isinstance(dimValue2, QName): # second dim is default value of an explicit dim
                    # multi-instance does not consider member's qname here where it is a default
                    # only check if qnames match if the facts are from same instance
                    if fact1.modelXbrl == fact2.modelXbrl and dimValue1 != dimValue2:
                        matches = False
                elif isinstance(dimValue2, ModelDimensionValue):
                    if dimValue2.isTyped:
                        matches = False
                    elif dimValue1 != dimValue2.memberQname:
                        matches = False 
                elif dimValue2 is None: # no dim aspect for fact 2
                    if fact1.modelXbrl == fact2.modelXbrl: # only allowed for multi-instance
                        matches = False
            elif dimValue1 is None:
                # absent dim member from fact1 allowed if fact2 is default in different instance
                if isinstance(dimValue2,QName):
                    if fact1.modelXbrl == fact2.modelXbrl:
                        matches = False
                elif dimValue2 is not None:
                    matches = False
                # else if both are None, matches True for single and multiple instance
        if not matches: 
            break
    return matches