Ejemplo n.º 1
0
def doc(xc, p, contextItem, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    uri = stringArg(xc, args, 0, "xs:string", emptyFallback=None)
    if uri is None:
        return ()
    if xc.progHeader is None or xc.progHeader.element is None:
        raise XPathContext.XPathException(
            p, 'err:FODC0005',
            _('Function xf:doc no formula resource element for {0}').format(
                uri))
    if not UrlUtil.isValid(uri):
        raise XPathContext.XPathException(
            p, 'err:FODC0005',
            _('Function xf:doc $uri is not valid {0}').format(uri))
    normalizedUri = xc.modelXbrl.modelManager.cntlr.webCache.normalizeUrl(
        uri,
        xc.progHeader.element.modelDocument.baseForElement(
            xc.progHeader.element))
    if normalizedUri in xc.modelXbrl.urlDocs:
        return xc.modelXbrl.urlDocs[normalizedUri].xmlDocument
    modelDocument = ModelDocument.load(xc.modelXbrl, normalizedUri)
    if modelDocument is None:
        raise XPathContext.XPathException(
            p, 'err:FODC0005',
            _('Function xf:doc $uri not successfully loaded {0}').format(uri))
    # assure that document is validated
    XmlValidate.validate(xc.modelXbrl, modelDocument.xmlRootElement)
    return modelDocument.xmlDocument
Ejemplo n.º 2
0
def replace(xc, p, contextItem, args):
    if not 3 <= len(args) <= 4: raise XPathContext.FunctionNumArgs()
    input = stringArg(xc, args, 0, "xs:string?", emptyFallback=())
    pattern = stringArg(xc, args, 1, "xs:string", emptyFallback=())
    fnReplacement = stringArg(xc, args, 2, "xs:string", emptyFallback=())
    if re.findall(r"(^|[^\\])[$]|[$][^0-9]", fnReplacement):
        raise XPathContext.XPathException(p, 'err:FORX0004', _('fn:replace pattern \'$\' error in: {0}').format(fnReplacement))
    reReplacement = re.sub(r"[\\][$]", "$", 
                         re.sub(r"(^|[^\\])[$]([1-9])", r"\\\2", fnReplacement))
    try:
        return re.sub(pattern,reReplacement,input,flags=regexFlags(xc, p, args, 3))
    except sre_constants.error as err:
        raise XPathContext.XPathException(p, 'err:FORX0002', _('fn:replace regular expression pattern error: {0}').format(err))
Ejemplo n.º 3
0
def fact_explicit_dimension_value_value(xc, p, args):
    context = item_context(xc, args)
    if context:
        qn = qnameArg(xc, p, args, 1, 'QName', emptyFallback=())
        if qn == (): raise XPathContext.FunctionArgType(2, "xbrl:QName")
        dimConcept = xc.modelXbrl.qnameConcepts.get(
            qn)  # check qname is explicit dimension
        if not dimConcept or not dimConcept.isExplicitDimension:
            raise XPathContext.XPathException(
                p, 'xfie:invalidExplicitDimensionQName',
                _('dimension does not specify an explicit dimension'))
        dimValue = context.dimValue(qn)
        if isinstance(dimValue,
                      ModelObject.ModelDimensionValue) and dimValue.isExplicit:
            return dimValue.memberQname  # known to be valid given instance is valid
        elif isinstance(dimValue, QName):  #default, check if this is valid
            ''' removed 2011-03-01 FWG clarification that default always applies
            modelItem = xc.modelItem(args[0][0])
            itemConcept = modelItem.concept
            from arelle.ValidateXbrlDimensions import checkPriItemDimValueValidity
            memConcept = xc.modelXbrl.qnameConcepts.get(dimValue)
            # remove check for pri item validity per FWG meeting notes 2011-01-13
            if itemConcept: # and checkPriItemDimValueValidity(xc, itemConcept, dimConcept, memConcept):
                return dimValue
            '''
            return dimValue
        return ()  # not an applicable primary item for default dimension
    raise XPathContext.FunctionArgType(1, "xbrl:item")
Ejemplo n.º 4
0
def concept(xc, p, args):
    qnConcept = qnameArg(xc, p, args, 0, 'QName', emptyFallback=None)
    srcConcept = xc.modelXbrl.qnameConcepts.get(qnConcept)
    if not (srcConcept and (srcConcept.isItem or srcConcept.isTuple)):
        raise XPathContext.XPathException(
            p, 'xfie:invalidConceptQName',
            _('Argument 1 {0} is not a concept in the DTS.').format(qnConcept))
    return srcConcept
Ejemplo n.º 5
0
def  format_number(xc, p, args):
    if len(args) != 2: raise XPathContext.FunctionNumArgs()
    value = numericArg(xc, p, args, 0, missingArgFallback='NaN', emptyFallback='NaN')
    picture = stringArg(xc, args, 1, "xs:string", missingArgFallback='', emptyFallback='')
    try:
        return format_picture(xc.modelXbrl.locale, value, picture)
    except ValueError as err:
        raise XPathContext.XPathException(p, 'err:FODF1310', str(err) )
Ejemplo n.º 6
0
def period_datetime(p, args, periodElement, addOneDay):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    if len(args[0]) != 1: raise XPathContext.FunctionArgType(1, "xbrl:period")
    period = args[0][0]
    if (isinstance(period, xml.dom.Node) and period.nodeType == 1
            and period.localName == "period"
            and period.namespaceURI == XbrlConst.xbrli):
        child = XmlUtil.child(period, XbrlConst.xbrli, periodElement)
        if child:
            return dateTime(child, addOneDay=addOneDay, type=DATETIME)
        elif periodElement == "instant":
            raise XPathContext.XPathException(p, 'xfie:PeriodIsNotInstant',
                                              _('Period is not instant'))
        else:
            raise XPathContext.XPathException(p, 'xfie:PeriodIsForever',
                                              _('Period is forever'))
    raise XPathContext.FunctionArgType(1, "xbrl:period")
Ejemplo n.º 7
0
def matches(xc, p, contextItem, args):
    if not 2 <= len(args) <= 3: raise XPathContext.FunctionNumArgs()
    input = stringArg(xc, args, 0, "xs:string?", emptyFallback=())
    pattern = stringArg(xc, args, 1, "xs:string", emptyFallback=())
    try:
        return bool(re.search(pattern,input,flags=regexFlags(xc, p, args, 2)))
    except sre_constants.error as err:
        raise XPathContext.XPathException(p, 'err:FORX0002', _('fn:matches regular expression pattern error: {0}').format(err))
Ejemplo n.º 8
0
def uncovered_aspect(xc, p, args):
    from arelle.ModelFormulaObject import aspectFromToken, Aspect
    from arelle.FormulaEvaluator import uncoveredAspectValue
    if len(args) not in (1, 2): raise XPathContext.FunctionNumArgs()
    aspect = aspectFromToken.get(stringArg(xc, args, 0, "xs:token").strip())
    if aspect == Aspect.DIMENSIONS:
        qn = qnameArg(xc, p, args, 1, 'QName', emptyFallback=None)

    # check function use after checking argument types
    if xc.progHeader and xc.progHeader.element:
        if xc.progHeader.element.localName not in ("formula",
                                                   "consistencyAssertion",
                                                   "valueAssertion",
                                                   "message"):
            raise XPathContext.XPathException(
                p, 'xffe:invalidFunctionUse',
                _('Function xff:uncovered-aspect cannot be used on an XPath expression associated with a {0}'
                  ).format(xc.progHeader.element.localName))
        if xc.variableSet and xc.variableSet.implicitFiltering == "false":
            raise XPathContext.XPathException(
                p, 'xffe:invalidFunctionUse',
                _('Function xff:uncovered-aspect cannot be used with implicitFiltering=false'
                  ))

    if aspect == Aspect.DIMENSIONS:
        if qn:
            modelConcept = xc.modelXbrl.qnameConcepts.get(qn)
            if modelConcept and modelConcept.isDimensionItem:
                aspect = qn
            else:
                return ()  # not a dimension
            dimValue = uncoveredAspectValue(xc, aspect)
            if isinstance(dimValue, ModelObject.ModelDimensionValue):
                if dimValue.isExplicit:
                    return dimValue.memberQname
                elif dimValue.isTyped:
                    return dimValue.typedMember
            elif isinstance(dimValue,
                            QName):  # qname for explicit or node for typed
                return dimValue
            return ()
    aspectValue = uncoveredAspectValue(xc, aspect)
    if aspectValue is None:
        return ()
    return aspectValue
Ejemplo n.º 9
0
def regexFlags(xc, p, args, n):
    f = 0
    flagsArg = stringArg(xc, args, n, "xs:string", missingArgFallback="", emptyFallback="")
    for c in flagsArg:
        if c == 's': f |= re.S
        elif c == 'm': f |= re.M
        elif c == 'i': f |= re.I
        elif c == 'x': f |= re.X
        else:
            raise XPathContext.XPathException(p, 'err:FORX0001', _('Regular expression interpretation flag unrecognized: {0}').format(flagsArg))
    return f
Ejemplo n.º 10
0
def fact_dim_value(xc, p, args, dimType):
    context = item_context(xc, args)
    qnDim = qnameArg(xc, p, args, 1, 'QName', emptyFallback=None)
    dimConcept = xc.modelXbrl.qnameConcepts.get(qnDim)
    if not dimConcept or not dimConcept.isDimensionItem:
        raise XPathContext.XPathException(
            p, 'xfie:invalid{0}DimensionQName'.format(dimType),
            _('Argument 1 {0} is not a dimension concept QName.').format(
                qnDim))
    if context:
        return context.dimValue(qnDim)
    raise XPathContext.FunctionArgType(1, "xbrl:item")
Ejemplo n.º 11
0
def call(xc, p, localname, args):
    source = atomicArg(xc, p, args, 0, "value?", missingArgFallback=() )
    if source == (): return source
    try:
        if localname not in xsFunctions: raise xsFunctionNotAvailable
        return xsFunctions[localname](xc, p, source)
    except (FORG0001, ValueError, TypeError):
        raise XPathContext.XPathException(p, 'err:FORG0001', 
                                          _('invalid cast from {0} to xs:{1}').format(
                                            type(source).__name__,
                                            localname))
    except xsFunctionNotAvailable:
        raise XPathContext.FunctionNotAvailable("xs:{0}".format(localname))
Ejemplo n.º 12
0
def infer_precision_decimals(xc, p, args, attrName):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    if len(args[0]) != 1: raise XPathContext.FunctionArgType(1, "xbrl:item")
    modelItem = xc.modelItem(args[0][0])
    if modelItem:
        modelConcept = modelItem.concept
        if modelConcept.isNumeric:
            if modelConcept.isFraction: return 'INF'
            from arelle.ValidateXbrlCalcs import (inferredDecimals,
                                                  inferredPrecision)
            p = inferredPrecision(
                modelItem) if attrName == "precision" else inferredDecimals(
                    modelItem)
            if isinf(p):
                return 'INF'
            if isnan(p):
                raise XPathContext.XPathException(
                    p, 'xfie:ItemIsNotNumeric',
                    _('Argument 1 {0} is not inferrable.').format(attrName))
            return p
    raise XPathContext.XPathException(
        p, 'xfie:ItemIsNotNumeric',
        _('Argument 1 is not reported with {0}.').format(attrName))
Ejemplo n.º 13
0
def fact_typed_dimension_value(xc, p, args):
    if len(args) != 2: raise XPathContext.FunctionNumArgs()
    context = item_context(xc, args)
    if context:
        qn = qnameArg(xc, p, args, 1, 'QName', emptyFallback=())
        if qn == (): raise XPathContext.FunctionArgType(2, "xbrl:QName")
        modelConcept = xc.modelXbrl.qnameConcepts.get(
            qn)  # check qname is explicit dimension
        if not modelConcept or not modelConcept.isTypedDimension:
            raise XPathContext.XPathException(
                p, 'xfie:invalidTypedDimensionQName',
                _('dimension does not specify a typed dimension'))
        result = context.dimValue(qn)
        return result.typedMember if result else ()
    raise XPathContext.FunctionArgType(1, "xbrl:item")
Ejemplo n.º 14
0
def boolean(xc, p, contextItem, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    inputSequence = args[0]
    if inputSequence is None or len(inputSequence) == 0:
        return False
    item = inputSequence[0]
    if isinstance(item, (ModelObject, ModelAttribute, etree._ElementTree)):
        return True
    if len(inputSequence) == 1:
        if isinstance(item, bool):
            return item
        if isinstance(item, _STR_BASE):
            return len(item) > 0
        if isinstance(item, _NUM_TYPES):
            return not math.isnan(item) and item != 0
    raise XPathContext.XPathException(p, 'err:FORG0006', _('Effective boolean value indeterminate'))
Ejemplo n.º 15
0
def boolean(xc, p, contextItem, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    inputSequence = args[0]
    if inputSequence is None or len(inputSequence) == 0:
        return False
    item = inputSequence[0]
    if isinstance(item, ModelObject.ModelObject) or isinstance(
            item, xml.dom.Node):
        return True
    if len(inputSequence) == 1:
        if isinstance(item, bool):
            return item
        if isinstance(item, str):
            return len(item) > 0
        if isinstance(item, int) or isinstance(item, float):
            return not math.isnan(item) and item != 0
    raise XPathContext.XPathException(
        p, 'err:FORG0006', _('Effective boolean value indeterminate'))
Ejemplo n.º 16
0
def filter_member_network_selection(xc, p, args):
    if len(args) != 5: raise XPathContext.FunctionNumArgs()
    qnDim = qnameArg(xc, p, args, 0, 'QName', emptyFallback=None)
    qnMem = qnameArg(xc, p, args, 1, 'QName', emptyFallback=None)
    linkroleURI = stringArg(xc, args, 2, "xs:string")
    arcroleURI = stringArg(xc, args, 3, "xs:string")
    axis = stringArg(xc, args, 4, "xs:string")
    if not axis in ('descendant-or-self', 'child-or-self', 'descendant',
                    'child'):
        return ()
    dimConcept = xc.modelXbrl.qnameConcepts.get(qnDim)
    if not dimConcept or not dimConcept.isDimensionItem:
        raise XPathContext.XPathException(
            p, 'xfie:invalidDimensionQName',
            _('Argument 1 {0} is not a dimension concept QName.').format(
                qnDim))
    memConcept = xc.modelXbrl.qnameConcepts.get(qnMem)
    if not memConcept or not memConcept.isDomainMember:
        # removed error 2011-03-10: raise XPathContext.XPathException(p, 'xfie:unrecognisedExplicitDimensionValueQName', _('Argument 1 {0} is not a member concept QName.').format(qnMem))
        return ()
    relationshipSet = xc.modelXbrl.relationshipSet(arcroleURI, linkroleURI)
    if relationshipSet:
        members = set()
        linkQnames = set()
        arcQnames = set()
        if axis.endswith("-or-self"):
            members.add(qnMem)
        fromRels = relationshipSet.fromModelObject(memConcept)
        if fromRels:
            filter_member_network_members(relationshipSet, fromRels,
                                          axis.startswith("descendant"),
                                          members, linkQnames, arcQnames)
            ''' removed 2011-03-10:
            if len(linkQnames) > 1 or len(arcQnames) > 1:
                raise XPathContext.XPathException(p, 'xfie:ambiguousFilterMemberNetwork', 
                          _('Network of linkrole {0} and arcrole {1} dimension {2} from {3} is ambiguous because of multiple link elements, {4}, or arc elements {5}').format(
                            linkroleURI, arcroleURI, qnDim, qnMem, linkQnames, arcQnames))
            '''
            return members
        # no fromRels, must be a toRel or else the qname is not in the member network
        if relationshipSet.toModelObject(memConcept):
            return members  # valid situation, the member exists as a leaf node
    # removed error 2011-03-10: raise XPathContext.XPathException(p, 'xfie:unrecognisedExplicitDimensionValueQName', _('Argument 1 {0} member is not in the network.').format(qnMem))
    return ()
Ejemplo n.º 17
0
def error(xc, p, contextItem, args):
    if len(args) > 2: raise XPathContext.FunctionNumArgs()
    qn = qnameArg(xc, p, args, 0, 'QName?', emptyFallback=None)
    msg = stringArg(xc, args, 1, "xs:string", emptyFallback='')
    raise XPathContext.XPathException(p, (qn or "err:FOER0000"), msg)