Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions render/Inline.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
(c) Copyright 2013 Mark V Systems Limited, All rights reserved.
'''
from arelle import ModelXbrl, ValidateXbrlDimensions, XbrlConst
from arelle.PluginManager import pluginClassMethods
from arelle.PrototypeDtsObject import LocPrototype, ArcPrototype
from arelle.ModelDocument import ModelDocument, ModelDocumentReference, Type, load
from arelle.ModelInstanceObject import ModelInlineFootnote
Expand Down Expand Up @@ -114,7 +113,7 @@ def saveTargetDocument(filing, modelXbrl, targetDocumentFilename, targetDocument
targetUrl = targetUrlParts[0] + suffix + targetUrlParts[2]
if suplSuffix: targetUrl += suplSuffix
modelXbrl.modelManager.showStatus(_("Extracting instance ") + os.path.basename(targetUrl))
for pluginXbrlMethod in pluginClassMethods("InlineDocumentSet.CreateTargetInstance"):
for pluginXbrlMethod in modelXbrl.modelManager.cntlr.plugins.hooks("InlineDocumentSet.CreateTargetInstance"):
targetInstance = pluginXbrlMethod(modelXbrl, targetUrl, targetDocumentSchemaRefs, filingFiles,
# no lang on xbrl:xbrl, specific xml:lang on elements which aren't en-US
baseXmlLang=None, defaultXmlLang="en-US", skipInvalid=True)
Expand Down
11 changes: 5 additions & 6 deletions render/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,10 @@

from collections import defaultdict
from arelle import PythonUtil
from arelle import (Cntlr, FileSource, ModelDocument, XmlUtil, Version, ModelValue, Locale, PluginManager, WebCache, ModelFormulaObject, Validate,
from arelle import (Cntlr, FileSource, ModelDocument, XmlUtil, Version, ModelValue, Locale, WebCache, ModelFormulaObject, Validate,
ViewFileFactList, ViewFileFactTable, ViewFileConcepts, ViewFileFormulae,
ViewFileRelationshipSet, ViewFileTests, ViewFileRssFeed, ViewFileRoleTypes)
from arelle.ModelInstanceObject import ModelFact, ModelInlineFootnote
from arelle.PluginManager import pluginClassMethods
from arelle.ValidateFilingText import elementsWithNoContent
from arelle.XhtmlValidate import xhtmlValidate
from arelle.XmlValidateConst import VALID, NONE, UNVALIDATED
Expand Down Expand Up @@ -722,7 +721,7 @@ def setProcessingFolder(self, filesource, entryPointFile=None):
else:
_url = filesource.url
# filesource.url may have an inline document set, trim it off
for pluginXbrlMethod in pluginClassMethods("InlineDocumentSet.Url.Separator"):
for pluginXbrlMethod in filesource.hooks("InlineDocumentSet.Url.Separator"):
inlineDocSetSeparator = pluginXbrlMethod()
_url = _url.partition(inlineDocSetSeparator)[0]
self.processingFolder = os.path.dirname(_url)
Expand Down Expand Up @@ -1192,7 +1191,7 @@ def copyResourceToReportFolder(filename, additionalDirectory=None):
IoManager.writeXmlDoc(filing, rootETree, self.reportZip, self.reportsFolder,
"PrivateFilingSummary.xml" if hasPrivateData and self.isWorkstationFirstPass else'FilingSummary.xml')
# generate supplemental AllReports and other such outputs at this time
for supplReport in pluginClassMethods("EdgarRenderer.FilingEnd.SupplementalReport"):
for supplReport in cntlr.plugins.hooks("EdgarRenderer.FilingEnd.SupplementalReport"):
supplReport(cntlr, filing, self.reportsFolder)
# if there's a dissem directory and no logs, remove summary logs
if (hasPrivateData or
Expand Down Expand Up @@ -1367,7 +1366,7 @@ def copyResourceToReportFolder(filename, additionalDirectory=None):
self.logDebug("Arelle viewer generated {:.3f} secs.".format(time.time() - _startedAt))
if self.isWorkstationFirstPass and not hasPrivateData:
_startedAt = time.time()
for generate in pluginClassMethods("iXBRLViewer.Generate"):
for generate in cntlr.plugins.hooks("iXBRLViewer.Generate"):
generate(cntlr, dissemReportsFolder, "/arelleViewer-1.4.11/ixbrlviewer.js", useStubViewer="ixbrlviewer.xhtml.dissem", saveStubOnly=True)
self.logDebug("Arelle viewer for dissemination generated {:.3f} secs.".format(time.time() - _startedAt))
self.logDebug(Summary.FilingSummaryCompletionMessage)
Expand Down Expand Up @@ -1554,7 +1553,7 @@ def copyResourceToReportFolder(filename, additionalDirectory=None):
elif self.isWorkstationFirstPass: # remove first pass excel report
pass # no excel output if no disseminated reports
# generate supplemental AllReports and other such outputs at this time
for supplReport in pluginClassMethods("EdgarRenderer.FilingEnd.SupplementalReport"):
for supplReport in cntlr.plugins.hooks("EdgarRenderer.FilingEnd.SupplementalReport"):
supplReport(cntlr, filing, dissemReportsFolder, zipDir="dissem/")
if generateiXBRLViewerStub:
_startedAt = time.time()
Expand Down
21 changes: 12 additions & 9 deletions render/iXBRLViewerInterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
"""

import io, os, sys, zipfile
from arelle.PluginManager import pluginClassMethods
from arelle import PluginManager

_iXBRLViewerPlugin = None
_iXBRLViewer_plugin_info = None
Expand All @@ -26,7 +24,7 @@ def hasIXBRLViewerPlugin(cntlr):
global _iXBRLViewerPlugin
if _iXBRLViewerPlugin is not None:
return True
if "ixbrl-viewer" not in PluginManager.pluginConfig["modules"]:
if "ixbrl-viewer" not in cntlr.plugins.get_plugins():
return False
try:
from arelle.plugin import iXBRLViewerPlugin as _iXBRLViewerPlugin
Expand All @@ -40,7 +38,7 @@ def generateViewer(cntlr, stubDir):
stubPath = os.path.join(stubDir, STUB_NAME)
securityIsActive = securityHasWritten = False
stubBytes = None
for pluginMethod in pluginClassMethods("Security.Crypt.IsActive"):
for pluginMethod in cntlr.plugins.hooks("Security.Crypt.IsActive"):
securityIsActive = pluginMethod(self) # must be active for the save method to save encrypted files
_iXBRLViewerPlugin.pluginData(cntlr).builder = _iXBRLViewerPlugin.IXBRLViewerBuilder(cntlr, useStubViewer = True)
_iXBRLViewerPlugin.processModel(cntlr, cntlr.modelManager.modelXbrl)
Expand All @@ -61,14 +59,19 @@ def generateViewer(cntlr, stubDir):
if not stubBytes:
return
if securityIsActive:
for pluginMethod in pluginClassMethods("Security.Crypt.Write"):
for pluginMethod in cntlr.plugins.hooks("Security.Crypt.Write"):
securityHasWritten = pluginMethod(self, stubPath, stubBytes)
if not securityHasWritten:
with open(stubPath, "wb") as fout:
fout.write(stubBytes)

def disableiXBRLViewerPluginInfo(cntlr):
if PluginManager.pluginConfig["modules"].get("ixbrl-viewer", {}).get("status", "disabled") == "enabled":
PluginManager.pluginConfig["modules"]["ixbrl-viewer"]["status"] = "disabled"
PluginManager.reset()
cntlr.addToLog(_("iXBRLViewer plugin disabled for EdgarRenderer. EdgarRenderer manages iXBRLViewer within its workflow."))
pluginMeta = cntlr.plugins.handles.get_plugins().get("ixbrl-viewer")
if pluginMeta is None:
return
if pluginMeta.status == "enabled":
cntlr.addToLog(
_("iXBRLViewer plugin should not be enabled for EdgarRenderer. "
"EdgarRenderer manages iXBRLViewer within its workflow."),
messageCode="arelle.ixbrlViewerPluginEnabled",
)
11 changes: 6 additions & 5 deletions validate/Filing.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
from arelle.ModelInstanceObject import ModelFact, ModelInlineFact, ModelInlineFootnote
from arelle.ModelDtsObject import ModelConcept, ModelResource
from arelle.ModelXbrl import NONDEFAULT
from arelle.PluginManager import pluginClassMethods
from arelle.PrototypeDtsObject import LinkPrototype, LocPrototype, ArcPrototype
from arelle.PythonUtil import pyNamedObject, strTruncate, normalizeSpace, lcStr, flattenSequence, flattenToSet, OrderedSet
from arelle.UrlUtil import isHttpUrl
Expand Down Expand Up @@ -145,8 +144,10 @@ def validateFiling(val, modelXbrl, isEFM=False, isGFM=False):
modelXbrl.isLoggingEffectiveFor(level="WARNING-SEMANTIC") or
modelXbrl.isLoggingEffectiveFor(level="ERROR-SEMANTIC"))

cntlr = modelXbrl.modelManager.cntlr

if isEFM:
for pluginXbrlMethod in pluginClassMethods("Validate.EFM.Start"):
for pluginXbrlMethod in cntlr.plugins.hooks("Validate.EFM.Start"):
pluginXbrlMethod(val)

if "EFM/Filing.py#validateFiling_start" in val.modelXbrl.arelleUnitTests:
Expand All @@ -168,7 +169,7 @@ def validateFiling(val, modelXbrl, isEFM=False, isGFM=False):
dqcRules = {}
isInlineXbrl = modelXbrl.modelDocument.type in (ModelDocument.Type.INLINEXBRL, ModelDocument.Type.INLINEXBRLDOCUMENTSET)
isXbrlInstance = isInlineXbrl or modelXbrl.modelDocument.type == ModelDocument.Type.INSTANCE
isFtJson = any(pluginXbrlMethod(modelXbrl) for pluginXbrlMethod in pluginClassMethods("FtJson.IsFtJsonDocument"))
isFtJson = any(pluginXbrlMethod(modelXbrl) for pluginXbrlMethod in cntlr.plugins.hooks("FtJson.IsFtJsonDocument"))
if isEFM:
if not attachmentDocumentType or not hasSubmissionType: # unspecified submission parameters (from cmd line or formula parameters dialog)
isFeeTagging = any(doc.targetNamespace.startswith("http://xbrl.sec.gov/ffd/") for doc in modelXbrl.urlDocs.values() if doc.targetNamespace)
Expand Down Expand Up @@ -602,7 +603,7 @@ def hasDeiFact(deiName):
extractedCoverFacts[f.qname.localName].append(f)

if isEFM: # note that this is in the "if context is not None" region. It does receive nil facts.
for pluginXbrlMethod in pluginClassMethods("Validate.EFM.Fact"):
for pluginXbrlMethod in cntlr.plugins.hooks("Validate.EFM.Fact"):
pluginXbrlMethod(val, f)
#6.5.17 facts with precision
concept = f.concept
Expand Down Expand Up @@ -5735,7 +5736,7 @@ def sumItemChildren(fromNames, toNames):
raise pyNamedObject(val.modelXbrl.arelleUnitTests["EFM/Filing.py#validateFiling_end"], "EFM/Filing.py#validateFiling_end")

if isEFM:
for pluginXbrlMethod in pluginClassMethods("Validate.EFM.Finally"):
for pluginXbrlMethod in cntlr.plugins.hooks("Validate.EFM.Finally"):
pluginXbrlMethod(val, conceptsUsed)
val.modelXbrl.profileActivity("... plug in '.Finally' checks", minTimeToShow=1.0)
val.modelXbrl.profileStat(_("validate{0}").format(modelXbrl.modelManager.disclosureSystem.validationType))
Expand Down
20 changes: 9 additions & 11 deletions validate/XuleInterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@
"""
import optparse, os, json
import regex as re
from arelle.plugin_system.plugin_meta import PluginMeta
import traceback
import sys
from arelle import PluginManager
from arelle.PythonUtil import attrdict, pyNamedObject
from .Util import usgaapYear

Expand Down Expand Up @@ -68,7 +68,7 @@
")")

"""Do not change anything below this line."""
_xule_plugin_info = None
_xule_plugin_info: PluginMeta | None = None
xuleValidateFinally = None
xulePluginDoesNotExist = False
user_defined_xule_rule_set = False
Expand Down Expand Up @@ -101,8 +101,8 @@ def close(cntlr): # unhook Xule's 'Validate.Finally' from validate/EFM
global xuleValidateFinally
'''
if xuleValidateFinally is not None:
PluginManager.modulePluginInfos[getXulePlugin(cntlr)["name"]]['Validate.Finally'] = xuleValidateFinally # restore original finally
PluginManager.reset()
cntlr._pluginManager.modulePluginInfos[getXulePlugin(cntlr).name]['Validate.Finally'] = xuleValidateFinally # restore original finally
cntlr._pluginManager.reset()
xuleValidateFinally = None
'''
def blockXuleValidateFinally(val):
Expand Down Expand Up @@ -314,10 +314,10 @@ def getXulePlugin(cntlr):
"""
global _xule_plugin_info, _incompatible_plugin, xulePluginDoesNotExist
if _xule_plugin_info is None and not xulePluginDoesNotExist:
for plugin_info in PluginManager.modulePluginInfos.values():
moduleUrl = plugin_info.get('moduleURL')
for plugin_meta in cntlr.plugins.get_plugins().values():
moduleUrl = plugin_meta.module_url
if moduleUrl.endswith('xule'):
_xule_plugin_info = plugin_info
_xule_plugin_info = plugin_meta
elif DQC_plugin_url_pattern.match(moduleUrl):
_incompatible_plugin = moduleUrl
cntlr.addToLog(_("EDGAR is not compatible with the DQC.py plugin, please remove the DQC.py plugin. The EDGAR plugin directly manages running of to run DQC rules."),
Expand All @@ -336,10 +336,8 @@ def getXuleMethod(cntlr, class_name):

Get a method/function from the Xule plugin. This is how this validator calls functions in the Xule plugin.
"""
xule_plugin = getXulePlugin(cntlr)
if xule_plugin is not None:
return xule_plugin.get(class_name)
return None
__ = getXulePlugin(cntlr) # Triggers logs if xule plugin is not available.
return next(cntlr.plugins.hooks(class_name), None)

def menuTools(cntlr, menu):
"""Add validator menu the Tools menu in the Arelle GUI
Expand Down
Loading