{"id":8227,"library":"imperfect","title":"Imperfect","description":"Imperfect is a Python library (version 0.4.0) designed for editing `configparser`-compatible INI files while preserving comments and whitespace. It operates by parsing configuration files into a Concrete Syntax Tree (CST) of nodes, allowing programmatic modifications that maintain the original file's structural integrity. The library is under active development with irregular releases.","status":"active","version":"0.4.0","language":"en","source_language":"en","source_url":"https://github.com/advice-animal/imperfect/","tags":["config","configparser","ini","cst","configuration","editor","parser"],"install":[{"cmd":"pip install imperfect","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"symbol":"ConfigFile","correct":"from imperfect import ConfigFile"},{"symbol":"parse_string","correct":"from imperfect import parse_string"}],"quickstart":{"code":"import imperfect\nimport io\n\n# Simulate an existing config file content\ninitial_config_content = '''\n[metadata]\n# the package name\nname = imperfect\n# slurp the readme\nlong_description = file: README.md\n\n[options]\npackages = imperfect\n'''\n\n# Parse the string content into an imperfect.ConfigFile object\nconf: imperfect.ConfigFile = imperfect.parse_string(initial_config_content)\n\n# Set a new value, it will be added at the end of the section by default\nconf.set_value(\"metadata\", \"long_description_content_type\", \"text/markdown\")\n\n# Print the modified content, preserving comments and whitespace\nprint(conf.text)","lang":"python","description":"This quickstart demonstrates how to parse an existing INI-style configuration string using `imperfect.parse_string`, modify a value using `set_value`, and then retrieve the modified content, showcasing the preservation of comments and whitespace."},"warnings":[{"fix":"Consult `configparser` documentation for detailed behavior, especially regarding edge cases, and test `imperfect`'s behavior thoroughly for critical parsing scenarios.","message":"Imperfect aims for compatibility with `configparser.RawConfigParser`, which includes replicating some of its longstanding 'odd behaviors' or bugs. Developers should be aware that certain quirks of `configparser` might be preserved rather than 'fixed'.","severity":"gotcha","affected_versions":"All versions"},{"fix":"For complex structural edits involving comments or specific whitespace, inspect and manipulate `ConfigEntry` objects directly rather than relying solely on high-level `set_value` methods. Review the output (`conf.text`) carefully after modifications.","message":"While `imperfect` is designed to preserve whitespace and comments, precise control over their exact placement when inserting or deleting entries can be complex. Direct manipulation of `ConfigEntry` objects might be required for fine-grained control.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Review any code that processes user-provided or external configuration files to ensure compatibility with the new unnamed section parsing behavior. Implement explicit validation if unnamed sections are still undesirable for your application.","message":"Version 0.4.0 introduced support for parsing unnamed sections. If previous application logic relied on older `imperfect` versions to reject (or not parse) configuration files containing unnamed sections, this change could alter behavior. Such files will now be processed.","severity":"gotcha","affected_versions":"0.4.0 and later"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Always refer to section and option names with their exact casing as present in the INI file. If migrating from `configparser.ConfigParser` where `optionxform = str` was not explicitly set, be mindful of casing.","cause":"`imperfect` aims for `RawConfigParser` compatibility, which defaults to case-sensitive section and option names. If you are accustomed to `configparser.ConfigParser` (which is case-insensitive by default), this can lead to lookup failures or incorrect behavior.","error":"KeyError: 'section_name' or unexpected behavior with casing of section/option names."},{"fix":"Ensure all modifications are performed using the `imperfect.ConfigFile` object's methods (e.g., `set_value`, direct manipulation of `ConfigEntry` objects within sections). Always use `conf.text` or `conf.build(file_object)` to retrieve or write the modified content to ensure CST-based preservation.","cause":"Attempting to manipulate the configuration content as a plain string, or mixing `imperfect`'s CST-based editing with direct string operations or standard `configparser` methods that do not preserve comments and whitespace.","error":"Modified configuration file loses comments, custom spacing, or has unexpected formatting after writing back."}]}