iniconfig
raw JSON → 2.3.0 verified Tue May 12 auth: no python install: verified quickstart: verified
iniconfig is a minimal, read-only INI-file parser maintained under the pytest-dev umbrella. It preserves section and key order, supports multi-line values, strips `#` comments from structure (not inline values in <2.3), raises `ParseError` with accurate line numbers, and rejects duplicate section names. Current stable version is 2.3.0, released 2024. Release cadence is irregular but healthy, driven by pytest ecosystem needs.
pip install iniconfig Common errors
error ModuleNotFoundError: No module named 'iniconfig' ↓
cause The 'iniconfig' package is not installed in your Python environment.
fix
pip install iniconfig
error iniconfig.ParseError: <filename>:<line_number>: no section header defined ↓
cause The INI file being parsed contains content before the first section header, or a section header is malformed or missing where expected.
fix
Ensure your .ini file starts with a valid section header, e.g.,
[section_name], and all subsequent sections are correctly defined. All content must belong to a section. error FileNotFoundError: [Errno 2] No such file or directory: '<file_path>' ↓
cause The path provided to `iniconfig.IniConfig()` does not point to an existing .ini file.
fix
Verify that the file path is correct and the .ini file exists at that location. Use an absolute path or ensure the file is in the current working directory or a correctly referenced path.
error KeyError: 'section_name' (or 'key_name') ↓
cause You are attempting to access a section or a key within a section using dictionary-style access (`ini['section']` or `ini['section']['key']`) that does not exist in the parsed INI configuration.
fix
Check the exact spelling and existence of the section and key in your .ini file. Use the
.get() method (e.g., ini.get('section', 'key') or ini['section'].get('key')) to safely retrieve values, which allows for a default return value if the key/section is not found, preventing a KeyError. Warnings
breaking v2.0.0 dropped Python 2 and older Python 3 (< 3.7) support and changed the packaging. The API surface stayed compatible, but pip will refuse to install 2.x on Python < 3.10 (requires_python >=3.10 as of 2.3.0). ↓
fix Use iniconfig==1.1.1 for Python < 3.10 environments, or upgrade the interpreter.
breaking Duplicate section names raise ParseError. Unlike stdlib configparser, iniconfig does NOT merge duplicates — the second occurrence is an error, not a silent override. ↓
fix Ensure each section name appears exactly once in the INI source before parsing.
gotcha Inline comments (e.g. `key = value # comment`) are NOT stripped by IniConfig() — the raw string including `# comment` is returned as the value. This differed silently from the README example in versions 2.0–2.2. ↓
fix Use IniConfig.parse() (added in 2.3.0) which does strip inline comments, or strip manually: value.split('#')[0].strip().
gotcha ini['section']['key'] raises KeyError — not returning None — when the section or key is absent. There is no .get() short-circuit on the section-level dict. ↓
fix Use ini.get(section, key, default) instead of direct bracket access for any optional key.
gotcha iniconfig is READ-ONLY. There is no write-back, set(), or save() method. Attempts to assign to ini['section']['key'] will raise TypeError or silently do nothing depending on the internal namedtuple/mapping type. ↓
fix Use stdlib configparser or a different library (e.g. configupdater) if you need to write or round-trip INI files.
deprecated The old py.iniconfig path (from the `py` / pylib package) was the predecessor of this standalone package. Any code doing `import py; py.iniconfig.IniConfig(...)` is using a long-deprecated shim. ↓
fix Replace `py.iniconfig` with `import iniconfig` and `iniconfig.IniConfig(...)`.
gotcha IniConfig constructor requires a path as its first positional argument even when parsing from a string via the `data=` kwarg. Passing `None` raises TypeError; pass a placeholder string like '-' or '<string>' instead. ↓
fix Always supply a non-None path: `IniConfig('-', data=my_string)`.
Install compatibility verified last tested: 2026-05-12
python os / libc status wheel install import disk
3.10 alpine (musl) - - 0.01s 17.8M
3.10 slim (glibc) - - 0.01s 18M
3.11 alpine (musl) - - 0.02s 19.7M
3.11 slim (glibc) - - 0.02s 20M
3.12 alpine (musl) - - 0.01s 11.5M
3.12 slim (glibc) - - 0.01s 12M
3.13 alpine (musl) - - 0.01s 11.2M
3.13 slim (glibc) - - 0.01s 12M
3.9 alpine (musl) - - 0.01s 17.3M
3.9 slim (glibc) - - 0.01s 18M
Imports
- IniConfig
import iniconfig ini = iniconfig.IniConfig('example.ini') - IniConfig (from string)
import iniconfig ini = iniconfig.IniConfig(path=None, data='[s]\nk=v\n') - IniConfig.parse (2.3+) wrong
iniconfig.IniConfig('f.ini') # inline comments NOT stripped before 2.3correctfrom iniconfig import IniConfig result = IniConfig.parse('[s]\nk=v # comment\n') - ParseError
from iniconfig import ParseError
Quickstart verified last tested: 2026-04-23
import iniconfig
INI_TEXT = """
[database]
host = localhost
port = 5432
names = foo,bar
[app]
debug = true
"""
# Parse from a string (no file needed)
ini = iniconfig.IniConfig("-", data=INI_TEXT)
# Direct access — raises KeyError if key/section missing
host = ini["database"]["host"] # 'localhost'
# Safe access with default + optional converter
port = ini.get("database", "port", 5432, int) # 5432 (int)
names = ini.get("database", "names", [], lambda x: x.split(",")) # ['foo', 'bar']
missing = ini.get("database", "user", "root") # 'root'
# Membership check
assert "database" in ini
assert "ghost" not in ini
# Iterate sections
for section in ini:
print(section.name, list(section.items()))
# Catch parse errors
try:
bad = iniconfig.IniConfig("-", data="[dup]\n[dup]\n")
except iniconfig.ParseError as exc:
print(f"Parse failed: {exc}")