def logArguments(self, codes, msg, codedArgs):
        def propValues(properties):
            # deref objects in properties
            return [(p[0],str(p[1])) if len(p) == 2 else (p[0],str(p[1]),propValues(p[2]))
                    for p in properties if 2 <= len(p) <= 3]
        # determine logCode
        messageCode = self.effectiveMessageCode(codes)
        
        # determine message and extra arguments
        fmtArgs = {}
        extras = {"messageCode":messageCode}
        modelObjectArgs = ()

        for argName, argValue in codedArgs.items():
            if argName in ("modelObject", "modelXbrl", "modelDocument"):
                try:
                    entryUrl = self.modelDocument.uri
                except AttributeError:
                    try:
                        entryUrl = self.entryLoadingUrl
                    except AttributeError:
                        entryUrl = self.fileSource.url
                refs = []
                modelObjectArgs = argValue if isinstance(argValue, (tuple,list,set)) else (argValue,)
                for arg in flattenSequence(modelObjectArgs):
                    if arg is not None:
                        if isinstance(arg, _STR_BASE):
                            objectUrl = arg
                        else:
                            try:
                                objectUrl = arg.modelDocument.uri
                            except AttributeError:
                                try:
                                    objectUrl = self.modelDocument.uri
                                except AttributeError:
                                    objectUrl = self.entryLoadingUrl
                        try:
                            file = UrlUtil.relativeUri(entryUrl, objectUrl)
                        except:
                            file = ""
                        ref = {}
                        if isinstance(arg,(ModelObject, ObjectPropertyViewWrapper)):
                            _arg = arg.modelObject if isinstance(arg, ObjectPropertyViewWrapper) else arg
                            ref["href"] = file + "#" + XmlUtil.elementFragmentIdentifier(_arg)
                            ref["sourceLine"] = _arg.sourceline
                            ref["objectId"] = _arg.objectId()
                            if self.logRefObjectProperties:
                                try:
                                    ref["properties"] = propValues(arg.propertyView)
                                except AttributeError:
                                    pass # is a default properties entry appropriate or needed?
                            if self.logRefHasPluginProperties:
                                refProperties = ref.get("properties", {})
                                for pluginXbrlMethod in pluginClassMethods("Logging.Ref.Properties"):
                                    pluginXbrlMethod(arg, refProperties, codedArgs)
                                if refProperties:
                                    ref["properties"] = refProperties
                        else:
                            ref["href"] = file
                            try:
                                ref["sourceLine"] = arg.sourceline
                            except AttributeError:
                                pass # arg may not have sourceline, ignore if so
                        if self.logRefHasPluginAttrs:
                            refAttributes = {}
                            for pluginXbrlMethod in pluginClassMethods("Logging.Ref.Attributes"):
                                pluginXbrlMethod(arg, refAttributes, codedArgs)
                            if refAttributes:
                                ref["customAttributes"] = refAttributes
                        refs.append(ref)
                extras["refs"] = refs
            elif argName == "sourceFileLine":
                # sourceFileLines is pairs of file and line numbers, e.g., ((file,line),(file2,line2),...)
                ref = {}
                if isinstance(argValue, (tuple,list)):
                    ref["href"] = str(argValue[0])
                    if len(argValue) > 1 and argValue[1]:
                        ref["sourceLine"] = str(argValue[1])
                else:
                    ref["href"] = str(argValue)
                extras["refs"] = [ref]
            elif argName == "sourceFileLines":
                # sourceFileLines is tuple/list of pairs of file and line numbers, e.g., ((file,line),(file2,line2),...)
                refs = []
                for arg in (argValue if isinstance(argValue, (tuple,list)) else (argValue,)):
                    ref = {}
                    if isinstance(arg, (tuple,list)):
                        ref["href"] = str(arg[0])
                        if len(arg) > 1 and arg[1]:
                            ref["sourceLine"] = str(arg[1])
                    else:
                        ref["href"] = str(arg)
                    refs.append(ref)
                extras["refs"] = refs
            elif argName == "sourceLine":
                if isinstance(argValue, _INT_TYPES):    # must be sortable with int's in logger
                    extras["sourceLine"] = argValue
            elif argName not in ("exc_info", "messageCodes"):
                if isinstance(argValue, (ModelValue.QName, ModelObject, bool, FileNamedStringIO,
                                         # might be a set of lxml objects not dereferencable at shutdown 
                                         tuple, list, set)):
                    fmtArgs[argName] = str(argValue)
                elif argValue is None:
                    fmtArgs[argName] = "(none)"
                elif isinstance(argValue, _INT_TYPES):
                    # need locale-dependent formatting
                    fmtArgs[argName] = format_string(self.modelManager.locale, '%i', argValue)
                elif isinstance(argValue,(float,Decimal)):
                    # need locale-dependent formatting
                    fmtArgs[argName] = format_string(self.modelManager.locale, '%f', argValue)
                elif isinstance(argValue, dict):
                    fmtArgs[argName] = argValue
                else:
                    fmtArgs[argName] = str(argValue)

        if "refs" not in extras:
            try:
                file = os.path.basename(self.modelDocument.uri)
            except AttributeError:
                try:
                    file = os.path.basename(self.entryLoadingUrl)
                except:
                    file = ""
            extras["refs"] = [{"href": file}]
        for pluginXbrlMethod in pluginClassMethods("Logging.Message.Parameters"):
            # plug in can rewrite msg string or return msg if not altering msg
            msg = pluginXbrlMethod(messageCode, msg, modelObjectArgs, fmtArgs) or msg
        return (messageCode, 
                (msg, fmtArgs) if fmtArgs else (msg,), 
                extras)
Tests whether a die is fair.
dataset/ETHPy150Open Arelle/Arelle/arelle/ModelXbrl.py/ModelXbrl.logArguments--crossover with--dataset/ETHPy150Open AllenDowney/CompStats/hypothesis.py/RunDiceTest