"configparser" --- Configuration file parser
********************************************

**Código fuente:** Lib/configparser.py

======================================================================

Este módulo provee la clase "ConfigParser", la cual implementa un
lenguaje básico de configuración que proporciona una estructura
similar a la encontrada en los archivos INI de Microsoft Windows.
Puedes utilizarla para escribir programas Python que los usuarios
finales puedan personalizar con facilidad.

Nota:

  Esta biblioteca *no* interpreta o escribe los prefijos valor-tipo
  usados en la versión extendida de la sintaxis INI, utilizada en el
  registro de Windows.

Ver también:

  Módulo "tomllib"
     TOML es un formato bien-especificado para archivos de
     configuración de aplicaciones. Está específicamente diseñado para
     ser una versión mejorada de INI.

  Módulo "shlex"
     Soporta la creación de un mini-lenguaje parecido a shell de Unix,
     que puede utilizarse para archivos de configuración de
     aplicaciones.

  Módulo "json"
     El módulo "json" implementa un subconjunto de la sintaxis de
     JavaScript, que también puede utilizarse para configuración, pero
     no soporta comentarios.


Inicio Rápido
=============

Tomemos un archivo de configuración muy básico, el cual luce así:

   [DEFAULT]
   ServerAliveInterval = 45
   Compression = yes
   CompressionLevel = 9
   ForwardX11 = yes

   [forge.example]
   User = hg

   [topsecret.server.example]
   Port = 50022
   ForwardX11 = no

La estructura de los archivos INI es descrita en la siguiente sección.
En esencia, el archivo consiste de secciones, cada una de las cuales
contiene claves con valores. Las clases "configparser" pueden leer y
escribir dichos archivos. Comencemos creando el anterior archivo de
configuración de forma programática.

   >>> import configparser
   >>> config = configparser.ConfigParser()
   >>> config['DEFAULT'] = {'ServerAliveInterval': '45',
   ...                      'Compression': 'yes',
   ...                      'CompressionLevel': '9'}
   >>> config['forge.example'] = {}
   >>> config['forge.example']['User'] = 'hg'
   >>> config['topsecret.server.example'] = {}
   >>> topsecret = config['topsecret.server.example']
   >>> topsecret['Port'] = '50022'     # mutates the parser
   >>> topsecret['ForwardX11'] = 'no'  # same here
   >>> config['DEFAULT']['ForwardX11'] = 'yes'
   >>> with open('example.ini', 'w') as configfile:
   ...   config.write(configfile)
   ...

Como puedes ver, podemos tratar al *config parser* como a un
diccionario. Existen diferencias,  descritas posteriormente, pero su
comportamiento es muy parecido al que esperarías de un diccionario.

Ahora que hemos creado y guardado el archivo de configuración, vamos a
releerlo y analizar los datos que contiene.

   >>> config = configparser.ConfigParser()
   >>> config.sections()
   []
   >>> config.read('example.ini')
   ['example.ini']
   >>> config.sections()
   ['forge.example', 'topsecret.server.example']
   >>> 'forge.example' in config
   True
   >>> 'python.org' in config
   False
   >>> config['forge.example']['User']
   'hg'
   >>> config['DEFAULT']['Compression']
   'yes'
   >>> topsecret = config['topsecret.server.example']
   >>> topsecret['ForwardX11']
   'no'
   >>> topsecret['Port']
   '50022'
   >>> for key in config['forge.example']:
   ...     print(key)
   user
   compressionlevel
   serveraliveinterval
   compression
   forwardx11
   >>> config['forge.example']['ForwardX11']
   'yes'

Como podemos apreciar, la API es muy clara. La única 'porción de
magia' está en la sección "DEFAULT", la cual proporciona los valores
por defecto para todas las demás secciones [1]. Observe también que
las claves de las secciones son insensibles a mayúsculas y minúsculas,
pero se almacenan en minúscula [1].

It is possible to read several configurations into a single
"ConfigParser", where the most recently added configuration has the
highest priority. Any conflicting keys are taken from the more recent
configuration while the previously existing keys are retained. The
example below reads in an "override.ini" file, which will override any
conflicting keys from the "example.ini" file.

   [DEFAULT]
   ServerAliveInterval = -1

   >>> config_override = configparser.ConfigParser()
   >>> config_override['DEFAULT'] = {'ServerAliveInterval': '-1'}
   >>> with open('override.ini', 'w') as configfile:
   ...     config_override.write(configfile)
   ...
   >>> config_override = configparser.ConfigParser()
   >>> config_override.read(['example.ini', 'override.ini'])
   ['example.ini', 'override.ini']
   >>> print(config_override.get('DEFAULT', 'ServerAliveInterval'))
   -1

Este comportamiento es equivalente a una llamada a
"ConfigParser.read()" pasando varios ficheros en el parámetro
*filenames*.


Tipos de Datos Soportados
=========================

Los *config parsers* no especulan respecto a los tipos de datos de los
valores en los archivos de configuración, siempre los almacenan
internamente como cadenas de caracteres. Esto significa que si
necesitas otros tipos de datos, deberás hacer la conversión por ti
mismo:

   >>> int(topsecret['Port'])
   50022
   >>> float(topsecret['CompressionLevel'])
   9.0

Dado que esta tarea es muy común, los *config parsers* proporcionan
una amplia variedad de útiles métodos de lectura (*getter*) que
manejan enteros, números de punto flotante y booleanos. Este último es
el más interesante, porque puede no ser correcto pasar simplemente el
valor a "bool()", ya que "bool('False')" resultará en "True". Por esta
razón los *config parsers* proporcionan también el método
"getboolean()". Este método es insensible a mayúsculas y minúsculas, y
reconoce como valores booleanos a los valores "'yes'"/"'no'",
"'on'"/"'off'", "'true'"/"'false'" and "'1'"/"'0'" [1].  Por ejemplo:

   >>> topsecret.getboolean('ForwardX11')
   False
   >>> config['forge.example'].getboolean('ForwardX11')
   True
   >>> config.getboolean('forge.example', 'Compression')
   True

Además de "getboolean()", los *config parsers* también proporcionan
los métodos equivalentes "getint()" y "getfloat()". Puedes registrar
tus propios conversores, y personalizar los que se proporcionan. [1]


Valores de contingencia
=======================

As with a dictionary, you can use a section's "get()" method to
provide fallback values:

   >>> topsecret.get('Port')
   '50022'
   >>> topsecret.get('CompressionLevel')
   '9'
   >>> topsecret.get('Cipher')
   >>> topsecret.get('Cipher', '3des-cbc')
   '3des-cbc'

Por favor, fíjate que los valores por defecto tienen prioridad sobre
los valores de contingencia (*fallback*). Así, en nuestro ejemplo, la
clave "'CompressionLevel'" sólo fue especificada en la sección
"'DEFAULT'". Si tratamos de obtener su valor de la sección
"'topsecret.server.example'", obtendremos siempre el valor por
defecto, incluso si especificamos un valor de contingencia:

   >>> topsecret.get('CompressionLevel', '3')
   '9'

One more thing to be aware of is that the parser-level "get()" method
provides a custom, more complex interface, maintained for backwards
compatibility.  When using this method, a fallback value can be
provided via the "fallback" keyword-only argument:

   >>> config.get('forge.example', 'monster',
   ...            fallback='No such things as monsters')
   'No such things as monsters'

El mismo argumento "fallback" puede utilizarse con los métodos
"getint()", "getfloat()" y "getboolean()", por ejemplo:

   >>> 'BatchMode' in topsecret
   False
   >>> topsecret.getboolean('BatchMode', fallback=True)
   True
   >>> config['DEFAULT']['BatchMode'] = 'no'
   >>> topsecret.getboolean('BatchMode', fallback=True)
   False


Estructura soportada para el archivo ini
========================================

Un archivo de configuración consta de secciones, cada una iniciada por
una cabecera "[section]", seguida por registros clave-valor separados
por una cadena de caracteres específica ("=" ó ":" por defecto [1]).
De forma predeterminada, los nombres de sección son sensibles a
mayúsculas y minúsculas pero las claves no [1]. Los espacios al inicio
y final de las claves y valores son eliminados. Los valores pueden ser
omitidos si el *parser* está configurado para permitirlo [1], en cuyo
caso el delimitador del dato clave-valor puede ser omitido también.
Los valores pueden ocupar varias líneas, siempre y cuando tengan una
indentación mayor que la primera línea del valor. Dependiendo del modo
del *parser*, las líneas en blanco pueden tratarse como parte de un
valor multilínea o ser ignoradas.

By default, a valid section name can be any string that does not
contain '\n'. To change this, see "ConfigParser.SECTCRE".

Los archivos de configuración pueden incluir comentarios, con
caracteres específicos como prefijos ("#" y ";" por defecto [1]). Los
comentarios pueden ocupar su propia línea, posiblemente indentada. [1]

Por ejemplo:

   [Simple Values]
   key=value
   spaces in keys=allowed
   spaces in values=allowed as well
   spaces around the delimiter = obviously
   you can also use : to delimit keys from values

   [All Values Are Strings]
   values like this: 1000000
   or this: 3.14159265359
   are they treated as numbers? : no
   integers, floats and booleans are held as: strings
   can use the API to get converted values directly: true

   [Multiline Values]
   chorus: I'm a lumberjack, and I'm okay
       I sleep all night and I work all day

   [No Values]
   key_without_value
   empty string value here =

   [You can use comments]
   # like this
   ; or this

   # By default only in an empty line.
   # Inline comments can be harmful because they prevent users
   # from using the delimiting characters as parts of values.
   # That being said, this can be customized.

       [Sections Can Be Indented]
           can_values_be_as_well = True
           does_that_mean_anything_special = False
           purpose = formatting for readability
           multiline_values = are
               handled just fine as
               long as they are indented
               deeper than the first line
               of a value
           # Did I mention we can indent comments, too?


Interpolación de valores
========================

En el nivel superior de su funcionalidad central, "ConfigParser"
soporta la interpolación. Esto significa que los valores pueden ser
preprocesados, antes de ser retornados por los llamados a "get()".

class configparser.BasicInterpolation

   Es la implementación por defecto que utiliza "ConfigParser".
   Permite valores que contengan cadenas de formato, que hacen
   referencia a otros valores en la misma sección o a valores
   presentes en la sección especial *default* [1]. Valores por defecto
   adicionales pueden ser proporcionados en la inicialización.

   Por ejemplo:

      [Paths]
      home_dir: /Users
      my_dir: %(home_dir)s/lumberjack
      my_pictures: %(my_dir)s/Pictures

      [Escape]
      # use a %% to escape the % sign (% is the only character that needs to be escaped):
      gain: 80%%

   En el ejemplo anterior, "ConfigParser" con la *interpolación*
   establecida a "BasicInterpolation()" puede resolver "%(home_dir)s"
   al valor "home_dir" ("/Users" en este caso).  En efecto,
   "%(my_dir)s" podría resolverse como "/Users/lumberjack". Todas las
   interpolaciones son realizadas bajo demanda, de modo que las claves
   utilizadas en la cadena de referencias no requieren un orden
   específico en el archivo de configuración.

   Con "interpolation" establecida al valor "None", el *parser*
   retornará simplemente "%(my_dir)s/Pictures" como el valor de
   "my_pictures" y "%(home_dir)s/lumberjack" como el valor de
   "my_dir".

class configparser.ExtendedInterpolation

   Es un gestor alternativo para la interpolación, que implementa una
   sintaxis más avanzada; es utilizado, por ejemplo, en "zc.buildout".
   La interpolación es extendida al utilizar "${section:option}", a
   fin de especificar un valor que proviene de una sección externa. La
   interpolación puede cubrir múltiples niveles. Por conveniencia, si
   la parte "section:" es omitida, la interpolación utilizará la
   sección actual (y posiblemente los valores por defecto establecidos
   en la sección especial).

   Por ejemplo, la configuración indicada anteriormente, con
   interpolación básica, luciría de la siguiente manera utilizando
   interpolación extendida:

      [Paths]
      home_dir: /Users
      my_dir: ${home_dir}/lumberjack
      my_pictures: ${my_dir}/Pictures

      [Escape]
      # use a $$ to escape the $ sign ($ is the only character that needs to be escaped):
      cost: $$80

   También pueden buscarse valores en otras secciones:

      [Common]
      home_dir: /Users
      library_dir: /Library
      system_dir: /System
      macports_dir: /opt/local

      [Frameworks]
      Python: 3.2
      path: ${Common:system_dir}/Library/Frameworks/

      [Arthur]
      nickname: Two Sheds
      last_name: Jackson
      my_dir: ${Common:home_dir}/twosheds
      my_pictures: ${my_dir}/Pictures
      python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python}


Acceso por protocolo de mapeo
=============================

Added in version 3.2.

El acceso por protocolo de mapeo es un nombre genérico asignado a la
funcionalidad que permite el uso de objetos personalizados como si
fuesen diccionarios. En el caso de "configparser", la implementación
de la interfaz de mapeo utiliza la notación
"parser['section']['option']".

En particular, "parser['section']" retorna un proxy para los datos de
la sección en el *parser*. Esto significa que los valores no son
copiados, sino que son tomados del *parser* original sobre la marcha.

Los objetos de "configparser" se comportan de forma tan similar a un
diccionario como se puede. La interfaz de mapeo es completa y se ciñe
a la "MutableMapping" ABC. Sin embargo, existen unas pequeñas
diferencias que deben tomarse en cuenta:

* Por defecto, todas las claves de las secciones se pueden acceder de
  una forma insensible a mayúsculas y minúsculas [1]. Ej. "for option
  in parser["section"]" entrega solamente nombres de claves de opción
  que han pasado por "optionxform". Esto significa, claves en
  minúscula por defecto. A la vez, para una sección que contiene la
  clave "'a'", ambas expresiones retornan "True":

     "a" in parser["section"]
     "A" in parser["section"]

* Todas las secciones también incluyen valores "DEFAULTSECT", lo que
  significa que ".clear()" en una sección puede no significar que esta
  quede vacía de forma visible. Ello debido a que los valores por
  defecto no pueden ser borrados de la sección (ya que técnicamente no
  están allí). Si fueron redefinidas en la sección, su borrado
  ocasiona que los valores por defecto sean visibles de nuevo.
  Cualquier intento de borrar un valor por defecto ocasiona una
  excepción "KeyError".

* "DEFAULTSECT" no puede ser eliminado del *parser*:

  * el intento de borrarlo lanza una excepción "ValueError",

  * "parser.clear()" lo deja intacto,

  * "parser.popitem()" nunca lo retorna.

* "parser.get(section, option, **kwargs)" - el segundo argumento
  **no** es un valor de contingencia. Observe, sin embargo, que los
  métodos "get()" a nivel de sección son compatibles tanto con el
  protocolo de mapeo como con la API clásica de *configparser*.

* "parser.items()" es compatible con el protocolo de mapeo (retorna
  una lista de pares *section_name*, *section_proxy* que estén
  incluidos en DEFAULTSECT). Sin embargo, este método también puede
  ser invocado con los argumentos: "parser.items(section, raw, vars)".
  Esta última llamada retorna una lista de pares *option*, *value*
  para una "section" específica, con todas las interpolaciones
  expandidas (a menos que se especifique "raw=True").

El protocolo de mapeo se implementa en el nivel superior de la actual
API heredada, de modo que esas subclases que sobre-escriben la
interfaz original aún deberían hacer funcionar el mapeo como se
esperaría.


Personalizando el comportamiento del parser
===========================================

Existen casi tantas variantes del formato INI como aplicaciones que lo
usen. "configparser" llega muy lejos al proporcionar soporte al mayor
conjunto sensible de estilos de INI disponibles. La funcionalidad
predeterminada es impuesta principalmente por antecedentes históricos
y es muy probable que quieras personalizar algunas de las
funcionalidades.

The most common way to change the way a specific config parser works
is to use the "__init__()" options:

* *defaults*, valor por defecto: "None"

  Esta opción acepta un diccionario de pares clave-valor, que debe ser
  colocado inicialmente en la sección "DEFAULT". De este modo se
  obtiene una manera elegante de apoyar los archivos de configuración
  concisos, que no especifican valores que sean los mismos
  documentados por defecto.

  Hint: if you want to specify default values for a specific section,
  use "read_dict()" before you read the actual file.

* *dict_type*, valor por defecto: "dict"

  Esta opción tiene un gran impacto en cómo funcionará el protocolo de
  mapeo, y cómo lucirán los archivos de configuración a escribir. Con
  el diccionario estándar, cada sección se almacena en el orden en que
  se añadieron al *parser*. Lo mismo ocurre con las opciones dentro de
  las secciones.

  Un tipo alternativo de diccionario puede ser utilizado, por ejemplo,
  para ordenar las secciones y opciones en un modo a posteriori
  (*write-back*).

  Por favor, tome en cuenta que: existen formas de agregar un par
  clave-valor en una sola operación. Cuando se utiliza un diccionario
  común en tales operaciones, el orden de las claves será el empleado
  en la creación. Por ejemplo:

     >>> parser = configparser.ConfigParser()
     >>> parser.read_dict({'section1': {'key1': 'value1',
     ...                                'key2': 'value2',
     ...                                'key3': 'value3'},
     ...                   'section2': {'keyA': 'valueA',
     ...                                'keyB': 'valueB',
     ...                                'keyC': 'valueC'},
     ...                   'section3': {'foo': 'x',
     ...                                'bar': 'y',
     ...                                'baz': 'z'}
     ... })
     >>> parser.sections()
     ['section1', 'section2', 'section3']
     >>> [option for option in parser['section3']]
     ['foo', 'bar', 'baz']

* *allow_no_value*, valor por defecto: "False"

  Se sabe que algunos archivos de configuración incluyen elementos sin
  indicar un valor, aunque cumplan con la sintaxis soportada por
  "configparser" en todo lo demás. El parámetro *allow_no_value* le
  indica al constructor que tales valores deben ser aceptados:

     >>> import configparser

     >>> sample_config = """
     ... [mysqld]
     ...   user = mysql
     ...   pid-file = /var/run/mysqld/mysqld.pid
     ...   skip-external-locking
     ...   old_passwords = 1
     ...   skip-bdb
     ...   # we don't need ACID today
     ...   skip-innodb
     ... """
     >>> config = configparser.ConfigParser(allow_no_value=True)
     >>> config.read_string(sample_config)

     >>> # Settings with values are treated as before:
     >>> config["mysqld"]["user"]
     'mysql'

     >>> # Settings without values provide None:
     >>> config["mysqld"]["skip-bdb"]

     >>> # Settings which aren't specified still raise an error:
     >>> config["mysqld"]["does-not-exist"]
     Traceback (most recent call last):
       ...
     KeyError: 'does-not-exist'

* *delimiters*, valor por defecto: "('=', ':')"

  Los *delimiters* son cadenas de caracteres que separan las claves de
  los valores dentro de una sección. La primera ocurrencia de una
  cadena de separación en una línea se considera como un separador.
  Esto significa que los valores pueden contener separadores, no así
  las claves.

  Vea también el argumento *space_around_delimiters* de
  "ConfigParser.write()".

* *comment_prefixes*, valor por defecto: "('#', ';')"

* *inline_comment_prefixes*, valor por defecto: "None"

  Los prefijos de comentario son cadenas de caracteres que indican el
  inicio de un comentario válido dentro de un archivo de
  configuración. Los *comment_prefixes* son utilizados solamente en lo
  que serían líneas en blanco (opcionalmente indentadas), mientras que
  *inline_comment_prefixes* pueden ser utilizados después de cada
  valor válido (ej. nombres de sección, opciones y también líneas en
  blanco). De forma predeterminada, los comentarios en la misma línea
  están deshabilitados, y tanto "'#'" como "';'" se utilizan como
  prefijos para comentarios que ocupan toda la línea.

  Distinto en la versión 3.2: En versiones previas de "configparser"
  el comportamiento correspondía a "comment_prefixes=('#',';')" e
  "inline_comment_prefixes=(';',)".

  Por favor, observe que los *config parsers* no soportan el escapado
  de los prefijos de comentarios, de modo que la utilización de los
  *inline_comment_prefixes* puede impedir que los usuarios
  especifiquen valores de opciones que incluyan caracteres empleados
  como prefijos de comentarios. Ante la duda, evite especificar los
  *inline_comment_prefixes*. En cualquier circunstancia, la única
  forma de almacenar caracteres prefijos de comentario al inicio de
  una línea, en valores multilínea, es mediante la interpolación del
  prefijo, por ejemplo:

     >>> from configparser import ConfigParser, ExtendedInterpolation
     >>> parser = ConfigParser(interpolation=ExtendedInterpolation())
     >>> # the default BasicInterpolation could be used as well
     >>> parser.read_string("""
     ... [DEFAULT]
     ... hash = #
     ...
     ... [hashes]
     ... shebang =
     ...   ${hash}!/usr/bin/env python
     ...   ${hash} -*- coding: utf-8 -*-
     ...
     ... extensions =
     ...   enabled_extension
     ...   another_extension
     ...   #disabled_by_comment
     ...   yet_another_extension
     ...
     ... interpolation not necessary = if # is not at line start
     ... even in multiline values = line #1
     ...   line #2
     ...   line #3
     ... """)
     >>> print(parser['hashes']['shebang'])

     #!/usr/bin/env python
     # -*- coding: utf-8 -*-
     >>> print(parser['hashes']['extensions'])

     enabled_extension
     another_extension
     yet_another_extension
     >>> print(parser['hashes']['interpolation not necessary'])
     if # is not at line start
     >>> print(parser['hashes']['even in multiline values'])
     line #1
     line #2
     line #3

* *strict*, valor por defecto: "True"

  When set to "True", the parser will not allow for any section or
  option duplicates while reading from a single source (using
  "read_file()", "read_string()" or "read_dict()").  It is recommended
  to use strict parsers in new applications.

  Distinto en la versión 3.2: En versiones previas de "configparser"
  el comportamiento correspondía a "strict=False".

* *empty_lines_in_values*, valor por defecto: "True"

  En los *config parsers*, los valores pueden abarcar varias líneas,
  siempre y cuando estén indentadas a un nivel superior al de la clave
  que las contiene. De forma predeterminada, los *parsers* permiten
  que las líneas en blanco formen parte de los valores. Igualmente,
  las claves pueden estar indentadas a sí mismas de forma arbitraria,
  a fin de mejorar la legibilidad. Por lo tanto, cuando los archivos
  de configuración se vuelven grandes y complejos, es fácil para el
  usuario el perder la pista de la estructura del archivo. Tomemos
  como ejemplo:

     [Section]
     key = multiline
       value with a gotcha

      this = is still a part of the multiline value of 'key'

  Esto puede ser especialmente problemático de observar por parte del
  usuario, en caso que se esté utilizando un tipo de fuente
  proporcional para editar el archivo. Y es por ello que, cuando tu
  aplicación no necesite valores con líneas en blanco, debes
  considerar invalidarlas. Esto ocasionaría que las líneas en blanco
  sirvan para dividir a las claves, siempre. En el ejemplo anterior,
  produciría dos claves: "key" y "this".

* *default_section*, valor por defecto: "configparser.DEFAULTSECT" (es
  decir: ""DEFAULT"")

  El convenio de permitir una sección especial con valores por defecto
  para otras secciones, o con propósito de interpolación, es un
  concepto poderoso de esta librería, el cual permite a los usuarios
  crear configuraciones declarativas complejas. Esta sección se suele
  denominar ""DEFAULT"", pero puede personalizarse para corresponder a
  cualquier otro nombre de sección. Algunas valores comunes son:
  ""general"" ó ""common"". El nombre proporcionado es utilizado para
  reconocer las secciones por defecto al momento de realizar la
  lectura desde cualquier fuente, y es utilizado ante cualquier
  escritura al archivo de configuración. Su valor actual puede
  obtenerse utilizando el atributo "parser_instance.default_section" y
  puede ser modificado en tiempo de ejecución (es decir, para
  convertir archivos de un formato a otro).

* *interpolation*, valor por defecto:
  "configparser.BasicInterpolation"

  El comportamiento de la interpolación puede ser personalizado al
  proporcionar un gestor personalizado mediante el argumento
  *interpolation*. El valor "None" se utiliza para desactivar la
  interpolación por completo, mientras que "ExtendedInterpolation()"
  proporciona una variante más avanzada, inspirada por "zc.buildout".
  Más información al respecto en la sección dedicada de la
  documentación. El "RawConfigParser" tiene un valor por defecto de
  "None".

* *converters*, valor por defecto: no definido

  Config parsers provide option value getters that perform type
  conversion.  By default "getint()", "getfloat()", and "getboolean()"
  are implemented.  Should other getters be desirable, users may
  define them in a subclass or pass a dictionary where each key is a
  name of the converter and each value is a callable implementing said
  conversion.  For instance, passing "{'decimal': decimal.Decimal}"
  would add "getdecimal()" on both the parser object and all section
  proxies.  In other words, it will be possible to write both
  "parser_instance.getdecimal('section', 'key', fallback=0)" and
  "parser_instance['section'].getdecimal('key', 0)".

  Si el conversor necesita acceder al estado del *parser*, este puede
  ser implementado como un método en una subclase del *config parser*.
  Si el nombre de este método comienza con "get", estará disponible en
  todas las secciones proxy, en su forma compatible con diccionarios
  (vea el ejemplo anterior de "getdecimal()").

Una personalización más avanzada puede conseguirse al sustituir los
valores por defecto de estos atributos del *parser*. Los valores por
defecto son definidos en las clases, de modo que pueden ser
sustituidos por las subclases o mediante la asignación de atributos.

ConfigParser.BOOLEAN_STATES

   Por defecto, al utilizar el método "getboolean()", los *config
   parsers* consideran a los siguientes valores como "True": "'1'",
   "'yes'", "'true'", "'on'" y a los siguientes valores como "False":
   "'0'", "'no'", "'false'", "'off'".  Puedes cambiar ello
   proporcionando un diccionario personalizado de cadenas de
   caracteres, con sus correspondientes valores booleanos. Por
   ejemplo:

      >>> custom = configparser.ConfigParser()
      >>> custom['section1'] = {'funky': 'nope'}
      >>> custom['section1'].getboolean('funky')
      Traceback (most recent call last):
      ...
      ValueError: Not a boolean: nope
      >>> custom.BOOLEAN_STATES = {'sure': True, 'nope': False}
      >>> custom['section1'].getboolean('funky')
      False

   Otros pares booleanos comunes incluyen "accept"/"reject" ó
   "enabled"/"disabled".

ConfigParser.optionxform(option)

   Este método realiza la transformación de los nombres de opciones
   para cada operación de lectura, obtención o asignación. Por defecto
   convierte los nombres a minúsculas. Esto significa que, cuando un
   archivo de configuración es escrito, todas las claves son
   convertidas a minúsculas. Sobre-escribe este método si tal
   comportamiento no es adecuado. Por ejemplo:

      >>> config = """
      ... [Section1]
      ... Key = Value
      ...
      ... [Section2]
      ... AnotherKey = Value
      ... """
      >>> typical = configparser.ConfigParser()
      >>> typical.read_string(config)
      >>> list(typical['Section1'].keys())
      ['key']
      >>> list(typical['Section2'].keys())
      ['anotherkey']
      >>> custom = configparser.RawConfigParser()
      >>> custom.optionxform = lambda option: option
      >>> custom.read_string(config)
      >>> list(custom['Section1'].keys())
      ['Key']
      >>> list(custom['Section2'].keys())
      ['AnotherKey']

   Nota:

     La función *optionxform* transforma los nombres de opción a una
     forma canónica. Esta debería ser una función idempotente: si el
     nombre ya está en su forma canónica, debería retornarse sin
     cambios.

ConfigParser.SECTCRE

   Es una expresión regular compilada que se utiliza para parsear
   cabeceras de sección. Por defecto hace corresponder "[section]" con
   el nombre ""section"". Los espacios en blanco son considerados
   parte del nombre de sección, por lo que "[  larch  ]" será leído
   como la sección de nombre ""  larch  "". Sobre-escribe este
   atributo si tal comportamiento no es adecuado. Por ejemplo:

      >>> import re
      >>> config = """
      ... [Section 1]
      ... option = value
      ...
      ... [  Section 2  ]
      ... another = val
      ... """
      >>> typical = configparser.ConfigParser()
      >>> typical.read_string(config)
      >>> typical.sections()
      ['Section 1', '  Section 2  ']
      >>> custom = configparser.ConfigParser()
      >>> custom.SECTCRE = re.compile(r"\[ *(?P<header>[^]]+?) *\]")
      >>> custom.read_string(config)
      >>> custom.sections()
      ['Section 1', 'Section 2']

   Nota:

     Mientras que los objetos *ConfigParser* también utilizan un
     atributo "OPTCRE" para reconocer las líneas de opciones, no se
     recomienda su sobre-escritura porque puede interferir con las
     opciones *allow_no_value* y *delimiters* del constructor.


Ejemplos de la API heredada
===========================

"configparser" proporciona también una API heredada con métodos
"get"/"set" explícitos; ello, principalmente debido a asuntos de
compatibilidad con versiones anteriores. Aunque existen casos de uso
válidos para los métodos descritos a continuación, se prefiere el
acceso por protocolo de mapeo para los proyectos nuevos. La API
heredada es al mismo tiempo más avanzada, de bajo nivel y sumamente
contradictoria.

Un ejemplo de escritura a un archivo de configuración:

   import configparser

   config = configparser.RawConfigParser()

   # Please note that using RawConfigParser's set functions, you can assign
   # non-string values to keys internally, but will receive an error when
   # attempting to write to a file or when you get it in non-raw mode. Setting
   # values using the mapping protocol or ConfigParser's set() does not allow
   # such assignments to take place.
   config.add_section('Section1')
   config.set('Section1', 'an_int', '15')
   config.set('Section1', 'a_bool', 'true')
   config.set('Section1', 'a_float', '3.1415')
   config.set('Section1', 'baz', 'fun')
   config.set('Section1', 'bar', 'Python')
   config.set('Section1', 'foo', '%(bar)s is %(baz)s!')

   # Writing our configuration file to 'example.cfg'
   with open('example.cfg', 'w') as configfile:
       config.write(configfile)

Un ejemplo de lectura de un archivo de configuración, nuevamente:

   import configparser

   config = configparser.RawConfigParser()
   config.read('example.cfg')

   # getfloat() raises an exception if the value is not a float
   # getint() and getboolean() also do this for their respective types
   a_float = config.getfloat('Section1', 'a_float')
   an_int = config.getint('Section1', 'an_int')
   print(a_float + an_int)

   # Notice that the next output does not interpolate '%(bar)s' or '%(baz)s'.
   # This is because we are using a RawConfigParser().
   if config.getboolean('Section1', 'a_bool'):
       print(config.get('Section1', 'foo'))

Para obtener la interpolación, utilice "ConfigParser":

   import configparser

   cfg = configparser.ConfigParser()
   cfg.read('example.cfg')

   # Set the optional *raw* argument of get() to True if you wish to disable
   # interpolation in a single get operation.
   print(cfg.get('Section1', 'foo', raw=False))  # -> "Python is fun!"
   print(cfg.get('Section1', 'foo', raw=True))   # -> "%(bar)s is %(baz)s!"

   # The optional *vars* argument is a dict with members that will take
   # precedence in interpolation.
   print(cfg.get('Section1', 'foo', vars={'bar': 'Documentation',
                                          'baz': 'evil'}))

   # The optional *fallback* argument can be used to provide a fallback value
   print(cfg.get('Section1', 'foo'))
         # -> "Python is fun!"

   print(cfg.get('Section1', 'foo', fallback='Monty is not.'))
         # -> "Python is fun!"

   print(cfg.get('Section1', 'monster', fallback='No such things as monsters.'))
         # -> "No such things as monsters."

   # A bare print(cfg.get('Section1', 'monster')) would raise NoOptionError
   # but we can also use:

   print(cfg.get('Section1', 'monster', fallback=None))
         # -> None

Los valores por defecto están disponibles en ambos tipos de
ConfigParsers. Ellos son utilizados en la interpolación cuando una
opción utilizada no está definida en otro lugar.

   import configparser

   # New instance with 'bar' and 'baz' defaulting to 'Life' and 'hard' each
   config = configparser.ConfigParser({'bar': 'Life', 'baz': 'hard'})
   config.read('example.cfg')

   print(config.get('Section1', 'foo'))     # -> "Python is fun!"
   config.remove_option('Section1', 'bar')
   config.remove_option('Section1', 'baz')
   print(config.get('Section1', 'foo'))     # -> "Life is hard!"


Objetos ConfigParser
====================

class configparser.ConfigParser(defaults=None, dict_type=dict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section=configparser.DEFAULTSECT, interpolation=BasicInterpolation(), converters={})

   La *config parser* principal. Si se proporciona *defaults*, su
   valor es inicializado en el diccionario de valores por defecto
   intrínsecos. Si se proporciona *dict_type*, se utiliza para crear
   el diccionario de objetos para la lista de secciones, las opciones
   dentro de una sección, y los valores por defecto.

   Si se proporciona *delimiters*, se utiliza como un conjunto de
   cadenas de caracteres que dividen las claves de los valores. Si se
   proporciona *comment_prefixes*, se utiliza como un conjunto de
   cadenas de caracteres que preceden a los comentarios, en líneas que
   estarían, de otro modo, vacías.  Los comentarios pueden estar
   indentados. Si se proporciona *inline_comment_prefixes*, se utiliza
   como un conjunto de cadenas de caracteres que preceden a los
   comentarios en líneas que no están vacías.

   Cuando *strict* es "True" (por defecto), el *parser* no permitirá
   duplicados en ninguna sección u opción, al realizar la lectura de
   una sola fuente (archivo, cadena de caracteres o diccionario),
   generando una excepción "DuplicateSectionError" ó
   "DuplicateOptionError".  Cuando *empty_lines_in_values* es "False"
   (valor por defecto: "True"), cada línea en blanco indica el fin de
   una opción.  De otro modo, las líneas en blanco de una opción
   multilínea son tratadas como parte del valor de esta. Cuando
   *allow_no_value* es "True" (valor por defecto: "False"), se aceptan
   opciones sin valores; el valor que toman esas opciones es "None" y
   serán serializadas sin el delimitador final.

   Cuando se proporciona *default_section*, se define el nombre de la
   sección especial que contiene valores por defecto para otras
   secciones y con propósito de interpolación (habitualmente
   denominada ""DEFAULT""). Este valor puede obtenerse y modificarse
   en tiempo de ejecución utilizando el atributo de instancia
   "default_section". Esto no volverá a evaluar un fichero de
   configuración previamente analizado sintácticamente (*parsed*),
   pero se usará al escribir configuraciones de analizado sintáctico
   (*parsed*) en un nuevo fichero de configuración.

   La interpolación puede personalizarse al proporcionar un gestor
   personalizado, mediante el argumento *interpolation*. El valor
   "None" se utiliza para desactivar la interpolación completamente,
   "ExtendedInterpolation()" proporciona una variante avanzada,
   inspirada en "zc.buildout". Más al respecto puede encontrarse en la
   correspondiente sección de la documentación.

   Todos los nombres de opción que se utilizan en la interpolación
   pasarán por el método "optionxform()", igual que cualquier otra
   referencia a un nombre de opción. Por lo tanto, si se utiliza la
   implementación por defecto de "optionxform()" (la cual convierte
   los nombres de opción a minúsculas), los valores "foo %(bar)s" y
   "foo %(BAR)s" son equivalentes.

   When *converters* is given, it should be a dictionary where each
   key represents the name of a type converter and each value is a
   callable implementing the conversion from string to the desired
   datatype.  Every converter gets its own corresponding "get*()"
   method on the parser object and section proxies.

   It is possible to read several configurations into a single
   "ConfigParser", where the most recently added configuration has the
   highest priority. Any conflicting keys are taken from the more
   recent configuration while the previously existing keys are
   retained. The example below reads in an "override.ini" file, which
   will override any conflicting keys from the "example.ini" file.

      [DEFAULT]
      ServerAliveInterval = -1

      >>> config_override = configparser.ConfigParser()
      >>> config_override['DEFAULT'] = {'ServerAliveInterval': '-1'}
      >>> with open('override.ini', 'w') as configfile:
      ...     config_override.write(configfile)
      ...
      >>> config_override = configparser.ConfigParser()
      >>> config_override.read(['example.ini', 'override.ini'])
      ['example.ini', 'override.ini']
      >>> print(config_override.get('DEFAULT', 'ServerAliveInterval'))
      -1

   Distinto en la versión 3.1: El valor por defecto de *dict_type* es
   "collections.OrderedDict".

   Distinto en la versión 3.2: se agregaron los argumentos
   *allow_no_value*, *delimiters*, *comment_prefixes*, *strict*,
   *empty_lines_in_values*, *default_section* y *interpolation*.

   Distinto en la versión 3.5: Se agregó el argumento *converters*.

   Distinto en la versión 3.7: The *defaults* argument is read with
   "read_dict()", providing consistent behavior across the parser:
   non-string keys and values are implicitly converted to strings.

   Distinto en la versión 3.8: El valor por defecto para *dict_type*
   es "dict", dado que este ahora preserva el orden de inserción.

   defaults()

      Retorna un diccionario que contiene los valores por defecto para
      toda la instancia.

   sections()

      Retorna una lista de las secciones disponibles; *default
      section* no se incluye en la lista.

   add_section(section)

      Agrega una sección llamada *section* a la instancia. Si ya
      existe una sección con el nombre proporcionado, se genera la
      excepción "DuplicateSectionError". Si se suministra el nombre
      *default section*, se genera la excepción "ValueError". El
      nombre de la sección debe ser una cadena de caracteres, de lo
      contrario, se genera la excepción "TypeError".

      Distinto en la versión 3.2: Nombres de sección que no sean del
      tipo cadena de caracteres generan la excepción "TypeError".

   has_section(section)

      Indica si la sección de nombre *section* existe en la
      configuración. No se permite *default section*.

   options(section)

      Retorna una lista de opciones disponibles en la sección
      especificada.

   has_option(section, option)

      Si la sección indicada existe, y esta contiene las opción
      proporcionada, retorna "True"; de lo contrario, retorna "False".
      Si la sección especificada es "None" o una cadena de caracteres
      vacía, se asume DEFAULT.

   read(filenames, encoding=None)

      Intenta leer y analizar sintácticamente (*parse*) un iterable de
      nombres de archivos, retornando una lista de nombres de archivos
      que han sido analizados (*parsed*) con éxito.

      Si *filenames* es una cadena de caracteres, un objeto "bytes" o
      un *path-like object*, es tratado como un simple nombre de
      archivo. Si un archivo mencionado en *filenames* no puede ser
      abierto, será ignorado. Está diseñado de forma que puedas
      especificar un iterable de potenciales ubicaciones para archivos
      de configuración (por ejemplo, el directorio actual, el
      directorio *home* del usuario, o algún directorio del sistema),
      y todos los archivos de configuración existentes serán leídos.

      Si no existe ninguno de los archivos mencionados, la instancia
      de "ConfigParser" contendrá un conjunto de datos vacío. Una
      aplicación que requiera valores iniciales, que sean cargados
      desde un archivo,  deberá cargar el(los) archivo(s) requerido(s)
      utilizando "read_file()" antes de llamar a "read()" para
      cualquier otro archivo opcional:

         import configparser, os

         config = configparser.ConfigParser()
         config.read_file(open('defaults.cfg'))
         config.read(['site.cfg', os.path.expanduser('~/.myapp.cfg')],
                     encoding='cp1250')

      Distinto en la versión 3.2: Added the *encoding* parameter.
      Previously, all files were read using the default encoding for
      "open()".

      Distinto en la versión 3.6.1: El parámetro *filenames* acepta un
      *path-like object*.

      Distinto en la versión 3.7: El parámetro *filenames* acepta un
      objeto "bytes".

   read_file(f, source=None)

      Leer y analizar (*parse*) los datos de configuración de *f*, el
      cual debe ser un iterable que retorne cadenas de caracteres
      Unicode (por ejemplo, archivos abiertos en modo texto).

      Optional argument *source* specifies the name of the file being
      read.  If not given and *f* has a "name" attribute, that is used
      for *source*; the default is "'<???>'".

      Added in version 3.2: Replaces "readfp()".

   read_string(string, source='<string>')

      Analiza (*parse*) los datos de configuración desde una cadena de
      caracteres.

      El argumento opcional *source* especifica un nombre para la
      cadena de caracteres proporcionada, relativo al contexto. Si no
      se proporciona, se utiliza "'<string>'". Esto, por lo general,
      debería ser una ruta de archivo o una URL.

      Added in version 3.2.

   read_dict(dictionary, source='<dict>')

      Carga la configuración a partir de cualquier objeto que
      proporcione un método "items()", similar a un diccionario. Las
      claves son nombres de secciones, los valores son diccionarios
      con claves y valores que deben estar presentes en la sección. Si
      el tipo de diccionario utilizado preserva el orden, las
      secciones y sus claves serán agregados en orden. Los valores son
      convertidos a cadenas de caracteres de forma automática.

      El argumento opcional *source* especifica un nombre para el
      diccionario proporcionado, relativo al contexto. Si no se
      proporciona, se utiliza "<dict>".

      Este método puede utilizarse para copiar el estado entre
      *parsers*.

      Added in version 3.2.

   get(section, option, *, raw=False, vars=None[, fallback])

      Obtiene el valor de una *option* para la sección indicada. Si se
      proporciona *vars*, tiene que ser un diccionario. El valor de
      *option* será buscado en *vars* (si se proporciona), en
      *section* y en *DEFAULTSECT*, en ese orden. Si la clave no se
      encuentra, y se ha proporcionado *fallback*, este es utilizado
      como un valor de contingencia. Se puede utilizar "None" como
      valor de contingencia (*fallback*).

      Todas las interpolaciones "'%'" son expandidas en el valor
      retornado, a menos que el argumento *raw* sea *true*. Los
      valores para la interpolación de las claves son buscados de la
      misma forma que para la opción.

      Distinto en la versión 3.2: Los argumentos *raw*, *vars* y
      *fallback* son argumentos nombrados solamente, a fin de proteger
      a los usuarios de los intentos de emplear el tercer argumento
      como el valor de contingencia de *fallback* (especialmente
      cuando se utiliza el protocolo de mapeo).

   getint(section, option, *, raw=False, vars=None[, fallback])

      Un cómodo método para forzar a entero el valor de la opción de
      la sección indicada. Revise "get()" para una explicación acerca
      de *raw*, *vars* y *fallback*.

   getfloat(section, option, *, raw=False, vars=None[, fallback])

      A convenience method which coerces the *option* in the specified
      *section* to a floating-point number.  See "get()" for
      explanation of *raw*, *vars* and *fallback*.

   getboolean(section, option, *, raw=False, vars=None[, fallback])

      Un cómodo método para forzar a booleano el valor de la opción de
      la sección indicada. Tome nota que los valores aceptados para la
      opción son "'1'", "'yes'", "'true'", and "'on'", para que el
      método retorne "True", y "'0'", "'no'", "'false'", y "'off'"
      para que el método retorne "False". Esos valores de cadenas de
      caracteres son revisados sin diferenciar mayúsculas de
      minúsculas. Cualquier otro valor ocasionará que se genere la
      excepción "ValueError". Revise "get()" para una explicación
      acerca de *raw*, *vars* y *fallback*.

   items(raw=False, vars=None)
   items(section, raw=False, vars=None)

      Cuando no se proporciona el argumento *section*, retorna una
      lista de pares *section_name*, *section_proxy*, incluyendo
      DEFAULTSECT.

      De lo contrario, retorna una lista de pares *name*, *value* para
      las opciones de la sección especificada. Los argumentos
      opcionales tienen el mismo significado que en el método "get()".

      Distinto en la versión 3.8: Los elementos que estén en *vars* no
      aparecen en el resultado. El comportamiento previo mezcla las
      opciones actuales del *parser* con las variables proporcionadas
      para la interpolación.

   set(section, option, value)

      Si la sección indicada existe, asigna el valor especificado a la
      opción indicada; en caso contrario, genera la excepción
      "NoSectionError". *option* y *value* deben ser cadenas de
      caracteres; de lo contrario, se genera la excepción "TypeError".

   write(fileobject, space_around_delimiters=True)

      Escribe una representación de la configuración al *file object*
      especificado, el cual debe ser abierto en modo texto (aceptando
      cadenas de caracteres). Esta representación puede ser analizada
      (*parsed*) por una posterior llamada a "read()". Si
      *space_around_delimiters* es *true*, los delimitadores entre
      claves y valores son rodeados por espacios.

   Nota:

     Los comentarios presentes en el fichero original no se mantienen
     cuando se vuelve a escribir la configuración. Qué es considerado
     un comentario depende de los valores asignados a *comment_prefix*
     e *inline_comment_prefix*.

   remove_option(section, option)

      Elimina la opción especificada de la sección indicada. Si la
      sección no existe, se genera una excepción "NoSectionError". Si
      la opción existía antes de la eliminación, retorna "True"; de lo
      contrario retorna "False".

   remove_section(section)

      Elimina la sección especificada de la configuración. Si la
      sección existía, retorna "True". De lo contrario, retorna
      "False".

   optionxform(option)

      Transforma el nombre de opción *option* de la forma en que se
      encontraba en el archivo de entrada o como fue pasada por el
      código del cliente, a la forma en que debe ser utilizada en las
      estructuras internas. La implementación por defecto retorna una
      versión en minúsculas de *option*; las subclases pueden sobre-
      escribirla o el código del cliente puede asignar un atributo de
      su nombre en las instancias, para afectar su comportamiento.

      No necesitas crear una subclase del *parser* para utilizar este
      método, ya que también puedes asignarlo en una instancia a una
      función, la cual reciba una cadena de caracteres como argumento
      y retorne otra. Por ejemplo, estableciéndola a "str", se hará
      que los nombres de opciones sean sensibles a mayúsculas y
      minúsculas:

         cfgparser = ConfigParser()
         cfgparser.optionxform = str

      Tome en cuenta que cuando se leen archivos de configuración, los
      espacios en blanco alrededor de los nombres de opción son
      eliminados antes de llamar a "optionxform()".

configparser.MAX_INTERPOLATION_DEPTH

   The maximum depth for recursive interpolation for "get()" when the
   *raw* parameter is false.  This is relevant only when the default
   *interpolation* is used.


Objetos RawConfigParser
=======================

class configparser.RawConfigParser(defaults=None, dict_type=dict, allow_no_value=False, *, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section=configparser.DEFAULTSECT[, interpolation])

   Variante heredada de "ConfigParser". Tiene la interpolación
   deshabilitada por defecto y permite nombres de sección que no sean
   cadenas de caracteres, nombres de opciones, y valores a través de
   sus métodos inseguros "add_section" y "set", así como el manejo
   heredado del argumento nombrado "defaults=".

   Distinto en la versión 3.8: El valor por defecto para *dict_type*
   es "dict", dado que este ahora preserva el orden de inserción.

   Nota:

     Considere el uso de "ConfigParser" en su lugar, el cual verifica
     los tipos de datos de los valores que se almacenarán
     internamente. Si no quieres la interpolación, puedes utilizar
     "ConfigParser(interpolation=None)".

   add_section(section)

      Agrega a la instancia una sección de nombre *section*. Si ya
      existe una sección con el nombre proporcionado, se genera la
      excepción "DuplicateSectionError". Si se suministra el nombre
      *default section*, se genera la excepción "ValueError".

      No se comprueba el tipo de datos de *section*, con lo cual se
      permite que los usuarios creen secciones con nombres que no sean
      cadenas de caracteres. Este comportamiento no está soportado y
      puede ocasionar errores internos.

   set(section, option, value)

      Si existe la sección indicada, asigna el valor especificado a la
      sección indicada; de lo contrario, genera la excepción
      "NoSectionError". Aunque es posible utilizar "RawConfigParser"
      (ó "ConfigParser" con parámetros *raw* con valor *true*) como
      almacenamiento interno para valores que no sean cadenas de
      caracteres, el funcionamiento completo (incluyendo la
      interpolación y escritura en archivos) sólo puede lograrse
      utilizando valores del tipo cadena de caracteres.

      Este método permite que los usuarios asignen valores que no sean
      cadenas de caracteres a las claves, internamente. Este
      comportamiento no está soportado y causará errores cuando se
      intente escribir en un archivo o cuando se intente obtenerlo en
      un modo no *raw*. **Utilice la API del protocolo de mapeo**, la
      cual no permite ese tipo de asignaciones.


Excepciones
===========

exception configparser.Error

   Clase base para todas las otras excepciones "configparser".

exception configparser.NoSectionError

   Excepción generada cuando no se encuentra una sección especificada.

exception configparser.DuplicateSectionError

   Exception raised if "add_section()" is called with the name of a
   section that is already present or in strict parsers when a section
   if found more than once in a single input file, string or
   dictionary.

   Distinto en la versión 3.2: Added the optional *source* and
   *lineno* attributes and parameters to "__init__()".

exception configparser.DuplicateOptionError

   Excepción generada por *parsers* estrictos si una sola opción
   aparece dos veces durante la lectura de un solo archivo, cadena de
   caracteres o diccionario. Captura errores de escritura o
   relacionados con el uso de mayúsculas y minúsculas, ej. un
   diccionario podría tener dos claves que representan la misma clave
   de configuración bajo un esquema insensible a mayúsculas y
   minúsculas.

exception configparser.NoOptionError

   Excepción generada cuando una opción especificada no se encuentra
   en una sección indicada.

exception configparser.InterpolationError

   Clase base para excepciones generadas por problemas que ocurren al
   realizar la interpolación de cadenas de caracteres.

exception configparser.InterpolationDepthError

   Excepción generada cuando la interpolación de cadenas de caracteres
   no puede completarse, debido a que el número de iteraciones excede
   a "MAX_INTERPOLATION_DEPTH". Subclase de "InterpolationError".

exception configparser.InterpolationMissingOptionError

   Excepción generada cuando no existe una opción referida por un
   valor. Subclase de "InterpolationError".

exception configparser.InterpolationSyntaxError

   Excepción generada cuando el texto fuente, donde se realizan las
   sustituciones, no se ajusta a la sintaxis requerida. Subclase de
   "InterpolationError".

exception configparser.MissingSectionHeaderError

   Excepción generada cuando se intenta analizar (*parse*) un archivo
   que no tiene encabezados de sección.

exception configparser.ParsingError

   Excepción generada cuando ocurren errores intentando analizar
   (*parse*) un archivo.

   Distinto en la versión 3.12: The "filename" attribute and
   "__init__()" constructor argument were removed.  They have been
   available using the name "source" since 3.2.

-[ Notas al pie ]-

[1] Los *config parsers* permiten una gran personalización. Si estás
    interesado en modificar el comportamiento descrito por la
    referencia de la nota al pie, consulta la sección Customizing
    Parser Behaviour.
