Preserve key case in a ConfigParser

By default, ConfigParser converts option names to lowercase. That is convenient for case-insensitive configuration, but it changes spelling such as APIKey when a parser reads and later writes an INI document. To preserve option-name case, set optionxform to str before reading or setting options. str returns each incoming option name unchanged, which is the idempotent canonicalization behavior the parser expects.

This example parses a [headers] section containing APIKey. The key list remains APIKey, retrieval using that exact spelling returns demo-token, and retrieval with lowercase apikey fails. The caught NoOptionError confirms the direct consequence of choosing case preservation: option lookup becomes case-sensitive. Section names have separate behavior and are case-sensitive by default regardless of this setting.

Configure optionxform before ingesting configuration, because names already read with the default transformer have already been lowercased. Case preservation does not make a value secret, validate a credential, or protect it in memory; the sample token is only inert demonstration text. The example uses APIs available in Python 3.2+ and no newer API. The optionxform documentation explains that it transforms names during read, get, and set operations and shows the identity-transform pattern.

AI assistance disclosure: This article was drafted with AI assistance and should be checked against the format expected by the consuming application.

import configparser

ini_text = "[headers]\nAPIKey = demo-token\n"
parser = configparser.ConfigParser()
parser.optionxform = str
parser.read_string(ini_text)

keys = list(parser["headers"].keys())
value = parser.get("headers", "APIKey")
assert keys == ["APIKey"]
assert value == "demo-token"

try:
    parser.get("headers", "apikey")
except configparser.NoOptionError:
    case_sensitive = True
else:
    case_sensitive = False

assert case_sensitive is True
print("keys={0}".format(",".join(keys)))
print("APIKey={0}".format(value))
print("case_sensitive={0}".format(case_sensitive))
keys=APIKey
APIKey=demo-token
case_sensitive=True

Comments

Popular posts from this blog

Compare Two Text Files in Python Without Modifying Them

Seven CSV Quality Checks to Run Before Importing Data

Explain why SQLite transactions cannot make an HTTP call atomic