class_docstr: Responsible for parsing configuration from files and CLI.
  
  There are 2 types of configurations: Run configurations and Check
  configurations.
  
  Run Configurations:
  ------------------
  Responsible for deciding things that are related to the user interface and
  configuration discovery, e.g. verbosity, debug options, etc.
  All run configurations default to `False` or `None` and are decided only
  by CLI.
  
  Check Configurations:
  --------------------
  Configurations that are related to which files and errors will be checked.
  These are configurable in 2 ways: using the CLI, and using configuration
  files.
  
  Configuration files are nested within the file system, meaning that the
  closer a configuration file is to a checked file, the more relevant it will
  be. For instance, imagine this directory structure:
  
  A
  +-- tox.ini: sets `select=D100`
  +-- B
      +-- foo.py
      +-- tox.ini: sets `add-ignore=D100`
  
  Then `foo.py` will not be checked for `D100`.
  The configuration build algorithm is described in `self._get_config`.
  
  Note: If any of `BASE_ERROR_SELECTION_OPTIONS` was selected in the CLI, all
  configuration files will be ignored and each file will be checked for
  the error codes supplied in the CLI.
class_docstr_tok: ["Responsible","for","parsing","configuration","from","files","and","CLI",".","There","are","2","types","of","configurations",":","Run","configurations","and","Check","configurations",".","Run","Configurations",":","--","--","--","--","--","--","--","--","--","Responsible","for","deciding","things","that","are","related","to","the","user","interface","and","configuration","discovery",",","e.g",".","verbosity",",","debug","options",",","etc",".","All","run","configurations","default","to","`","False","`","or","`","None","`","and","are","decided","only","by","CLI",".","Check","Configurations",":","--","--","--","--","--","--","--","--","--","--","Configurations","that","are","related","to","which","files","and","errors","will","be","checked",".","These","are","configurable","in","2","ways",":","using","the","CLI",",","and","using","configuration","files",".","Configuration","files","are","nested","within","the","file","system",",","meaning","that","the","closer","a","configuration","file","is","to","a","checked","file",",","the","more","relevant","it","will","be",".","For","instance",",","imagine","this","directory","structure",":","A","+","--","tox.ini",":","sets","`","select=D100","`","+","--","B","+","--","foo.py","+","--","tox.ini",":","sets","`","add-ignore=D100","`","Then","`","foo.py","`","will","not","be","checked","for","`","D100","`",".","The","configuration","build","algorithm","is","described","in","`","self._get_config","`",".","Note",":","If","any","of","`","BASE_ERROR_SELECTION_OPTIONS","`","was","selected","in","the","CLI",",","all","configuration","files","will","be","ignored","and","each","file","will","be","checked","for","the","error","codes","supplied","in","the","CLI","."]
docstr: Try to read and parse `path` as a configuration file.
  
  If the configurations were illegal (checked with
  `self._validate_options`), raises `IllegalConfiguration`.
  
  Returns (options, should_inherit).
docstr_tok: ["Try","to","read","and","parse","`","path","`","as","a","configuration","file",".","If","the","configurations","were","illegal","(","checked","with","`","self._validate_options","`",")",",","raises","`","IllegalConfiguration","`",".","Returns","(","options",",","should_inherit",")","."]
code: def _read_configuration_file(self, path):
      """Try to read and parse `path` as a configuration file.
  
      If the configurations were illegal (checked with
      `self._validate_options`), raises `IllegalConfiguration`.
  
      Returns (options, should_inherit).
  
      """
      if path.endswith(".toml"):
          parser = TomlParser()
      else:
          parser = RawConfigParser(inline_comment_prefixes=("#", ";"))
      options = None
      should_inherit = True
  
      if parser.read(path) and self._get_section_name(parser):
          all_options = self._parser.option_list[:]
          for group in self._parser.option_groups:
              all_options.extend(group.option_list)
  
          option_list = {
              o.dest: o.type or o.action for o in all_options
          }
  
          # First, read the default values
          new_options, _ = self._parse_args([])
  
          # Second, parse the configuration
          section_name = self._get_section_name(parser)
          for opt in parser.options(section_name):
              if opt == "inherit":
                  should_inherit = parser.getboolean(section_name, opt)
                  continue
  
              if opt.replace("_", "-") not in self.CONFIG_FILE_OPTIONS:
                  log.warning(f"Unknown option '{opt}' ignored")
                  continue
  
              normalized_opt = opt.replace("-", "_")
              opt_type = option_list[normalized_opt]
              if opt_type in ("int", "count"):
                  value = parser.getint(section_name, opt)
              elif opt_type == "string":
                  value = parser.get(section_name, opt)
              else:
                  assert opt_type in ("store_true", "store_false")
                  value = parser.getboolean(section_name, opt)
              setattr(new_options, normalized_opt, value)
  
          # Third, fix the set-options
          options = self._fix_set_options(new_options)
  
      if options is not None:
          if not self._validate_options(options):
              raise IllegalConfiguration(f"in file: {path}")
  
      return options, should_inherit
  
imports: import copy
  import itertools
  import operator
  import os
  import sys
  from collections import namedtuple
  from collections.abc import Set
  from configparser import NoOptionError, NoSectionError, RawConfigParser
  from functools import reduce
  from re import compile
  from ._version import __version__
  from .utils import log
  from .violations import ErrorRegistry, conventions
label_desc: Use image node_id 9 for calling the ConfigurationParser obj's underlying member method code with example usage: obj._read_configuration_file(path) and returns: options,  should_inherit