# m9ini Configuration Library
**m9ini** is a python library for reading configuration files bases on the INI format.
This library has many advanced features, including:
- Sections can be identified by name, class, or label
- Rules for default and overriding property values
- Name-value sections and text-block sections
- String substitution using properties in the same or other section
- Object-oriented section inheritance and expansion
- Robust features for programmatic access
An easy-to-use demonstration of these features is found at [m9ini-demo](https://github.com/MarcusNyne/m9ini-demo).
## Advanced feature reference
This page contains information about basic configuration file features.
Advanced features are found on other doc pages:
- [Substitution](docs/config_subst.md): Replace placeholder strings with section property values
- [Section linking](docs/config_slinks.md): Establish links and references to other sections
- [Section expansion](docs/config_expansion.md): Dynamically generate section variations
- [Programmatic access](docs/config_prog.md): Access configuration files from Python
- [Quick reference](docs/config_quick.md): Syntax quick reference
- [Troubleshooting](docs/config_troubles.md): Tips for troubleshooting syntax or runtime issues
- [Error messages](docs/config_errors.md): A list of error messages with troubleshooting tips
## Config File Format
```ini
@<ini-filepath>
; includes another configuration file
setting=value
# global settings (before any section headers)
[<section>]
# section name, which is the default "class name"
[<section>:<id>]
# section with id
[<section>:<id>:<label1>,<label2>, .. ,<labelN>]
# section with id and label(s)
[*default:<section>:<id>:<labels>]
# default values for a section
[*override:<section>:<id>:<labels>]
# override values for a section
# section header overrides
*id=<id> # section id (defaults to id from section header)
*class=<class> # section class (defaults to name from section header)
*label=<labels> # one or more labels as a comma-delimited list
# section property
setting=value
# link to another section
other_section=><section>:<id>:<label>
# a text block is a section without name-values, just a list of strings
[[<section>:<id>:<labels>]]
line 1
line 2
line 3
# dynamically create N sections based on (the number of base sections) * (the number of property variations)
# => [] contains rules for matching a base section (can be blank)
# properties are inherited from the base section
# setting values containing a pipe ("|") define property variations
[<section>:<id>:<labels>] => [<section>:<id>]
setting=value1|value2
```
### Include files
The syntax to include another ini file is: `@<ini_file>`. The ".ini" extension is optional.
If an include file is not found, the entire load will failure. Information about missing include files is available from [**GetFailures()**](config_troubles.md#error-access).
If an include file is referenced more than once (or recursively), a warning is issued, but the load operation continues. The include file is only loaded once.
```ini
# these lines are equivalent
@myfile
@myfile.ini
# you may specify a path to the file
@subfolder\myfile
# in this example, myfile.ini is only loaded once even though it is included twice, with the following warning
# [F06] Warning: Duplicate/recursive include file reference detected
```
### Comments
Comments may begin with `#` or `;`.
```ini
# a comment
; a comment
```
### Config sections
A section header is specified in square brackets and includes a section name followed by an optional id and list of labels in the format `[<name>:<id>:<labels>]`.
- `<name>`: represents a section "class". Sections with similar purpose and properties should have the same name.
- `<id>`: an identifier. Not required to be unique.
- `<label>`: a comma-delimited list of labels
Config sections contain name-value pairs. There are three reserved values:
- `*id` is synonomous with the section id
- `*class` may specify a class value (defaults to section name)
- `*label` contains a comma-delimited list of labels
After the INI file is read, sections can be accessed by name, id, or label using a "section specification".
```ini
# these are some examples of section headers
[section_a]
[section_b:my_id]
[section_c::label1,label2]
[section_d]
*id=my_id
[section_e:some_id]
*class=my_class
*label=label1,label2
```
### Section specification
A section specification is a rule that matches one or more configuration sections based on the section *name*, *id*, and/or *label* as a string in this format: `<name>:<id>:<label>`. Any or all components of the section specification can be specified left to right. For example: `<name>`, `<name>:<id>`, or `<name>:<id>:<label>`.
The following combinations are supported:
- `<name>`
- `<name>:<id>`
- `:<id>`
- `:<id>:<label>`
- `::<label>`
- `<name>:<id>:<label>`
- `<name>::<label>`
If any of these start with $, it is interpreted as "starts with". When multiple parts are specified, all parts must be satisfied. An empty specification matches all sections.
### Text block sections
A text block is a section that is read as many lines under the section header without any properties.
The section header of a text block follows the same identification rules as a normal section header, but is wrapped with double brackets.
```ini
[[mytext:text_id]]
line 1
another line
# comments are ignored
blank line above is captured
```
### Default and override rules
Default and override values may be specified with a "section specification" in the section header.
Section header rules are specified as `<name>:<id>:<label>`, with all these being optional. When multiple are specified, all must be true. When none are specified, all sections match.
For example: `[*default:$mycl::mylabel]` will provide default values for all sections that start with "mycl" and have the label "mylabel".
For example: `[*override::myid]` will provide override values for all sections with the id "myid".
- A property need not exist in a target section for the property to be added by a default or override rule
- When a property is found in multiple default or override sections, the first to appear will take priority
- A "*level" property may be added to a default or override section to set the priority level
- The default priority is 0
- Lower levels take priority
- Priorities may be negative
```ini
[*default:MySection]
One=Bananas
Two=Strawberries
Three=Peaches
[MySection]
One=Red
Two=Blue
[*default:MySection]
Three=Black
[*override:MySection]
Two=Violet
[*override:MySection]
*level=-1
Two=Pink
# [=>MySection.One] is "Red"
# [=>MySection.Two] is "Pink"
# [=>MySection.Three] is "Peaches"
```
Raw data
{
"_id": null,
"home_page": null,
"name": "m9ini",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10.6",
"maintainer_email": null,
"keywords": "INI, configuration, config, settings, parse, load, batch",
"author": "M. Fairbanks",
"author_email": "marcusnyne@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/97/67/f8ac7081085dbffee2d2f20b890f1decae591c1f2fda721ba3585a479c15/m9ini-1.0.1.tar.gz",
"platform": null,
"description": "# m9ini Configuration Library\n\n**m9ini** is a python library for reading configuration files bases on the INI format.\n\nThis library has many advanced features, including:\n- Sections can be identified by name, class, or label\n- Rules for default and overriding property values\n- Name-value sections and text-block sections\n- String substitution using properties in the same or other section\n- Object-oriented section inheritance and expansion\n- Robust features for programmatic access\n\nAn easy-to-use demonstration of these features is found at [m9ini-demo](https://github.com/MarcusNyne/m9ini-demo).\n\n## Advanced feature reference\n\nThis page contains information about basic configuration file features.\n\nAdvanced features are found on other doc pages:\n- [Substitution](docs/config_subst.md): Replace placeholder strings with section property values\n- [Section linking](docs/config_slinks.md): Establish links and references to other sections\n- [Section expansion](docs/config_expansion.md): Dynamically generate section variations\n- [Programmatic access](docs/config_prog.md): Access configuration files from Python\n- [Quick reference](docs/config_quick.md): Syntax quick reference\n- [Troubleshooting](docs/config_troubles.md): Tips for troubleshooting syntax or runtime issues\n- [Error messages](docs/config_errors.md): A list of error messages with troubleshooting tips\n\n## Config File Format\n\n```ini\n@<ini-filepath>\n; includes another configuration file\n\nsetting=value\n# global settings (before any section headers)\n\n[<section>]\n# section name, which is the default \"class name\"\n[<section>:<id>]\n# section with id\n[<section>:<id>:<label1>,<label2>, .. ,<labelN>]\n# section with id and label(s)\n[*default:<section>:<id>:<labels>]\n# default values for a section\n[*override:<section>:<id>:<labels>]\n# override values for a section\n\n# section header overrides\n*id=<id> # section id (defaults to id from section header)\n*class=<class> # section class (defaults to name from section header)\n*label=<labels> # one or more labels as a comma-delimited list\n\n# section property\nsetting=value\n\n# link to another section\nother_section=><section>:<id>:<label>\n\n# a text block is a section without name-values, just a list of strings\n[[<section>:<id>:<labels>]]\nline 1\nline 2\nline 3\n\n# dynamically create N sections based on (the number of base sections) * (the number of property variations)\n# => [] contains rules for matching a base section (can be blank)\n# properties are inherited from the base section\n# setting values containing a pipe (\"|\") define property variations\n[<section>:<id>:<labels>] => [<section>:<id>]\nsetting=value1|value2\n```\n\n### Include files\n\nThe syntax to include another ini file is: `@<ini_file>`. The \".ini\" extension is optional.\n\nIf an include file is not found, the entire load will failure. Information about missing include files is available from [**GetFailures()**](config_troubles.md#error-access).\n\nIf an include file is referenced more than once (or recursively), a warning is issued, but the load operation continues. The include file is only loaded once.\n\n```ini\n# these lines are equivalent\n@myfile\n@myfile.ini\n# you may specify a path to the file\n@subfolder\\myfile\n\n# in this example, myfile.ini is only loaded once even though it is included twice, with the following warning\n# [F06] Warning: Duplicate/recursive include file reference detected\n```\n\n### Comments\n\nComments may begin with `#` or `;`.\n\n```ini\n# a comment\n; a comment\n```\n\n### Config sections\n\nA section header is specified in square brackets and includes a section name followed by an optional id and list of labels in the format `[<name>:<id>:<labels>]`.\n- `<name>`: represents a section \"class\". Sections with similar purpose and properties should have the same name.\n- `<id>`: an identifier. Not required to be unique.\n- `<label>`: a comma-delimited list of labels\n\nConfig sections contain name-value pairs. There are three reserved values:\n- `*id` is synonomous with the section id\n- `*class` may specify a class value (defaults to section name)\n- `*label` contains a comma-delimited list of labels\n\nAfter the INI file is read, sections can be accessed by name, id, or label using a \"section specification\".\n\n```ini\n# these are some examples of section headers\n[section_a]\n[section_b:my_id]\n[section_c::label1,label2]\n[section_d]\n*id=my_id\n[section_e:some_id]\n*class=my_class\n*label=label1,label2\n```\n\n### Section specification\n\nA section specification is a rule that matches one or more configuration sections based on the section *name*, *id*, and/or *label* as a string in this format: `<name>:<id>:<label>`. Any or all components of the section specification can be specified left to right. For example: `<name>`, `<name>:<id>`, or `<name>:<id>:<label>`.\n\nThe following combinations are supported:\n - `<name>`\n - `<name>:<id>`\n - `:<id>`\n - `:<id>:<label>`\n - `::<label>`\n - `<name>:<id>:<label>`\n - `<name>::<label>`\n\nIf any of these start with $, it is interpreted as \"starts with\". When multiple parts are specified, all parts must be satisfied. An empty specification matches all sections.\n\n### Text block sections\n\nA text block is a section that is read as many lines under the section header without any properties.\n\nThe section header of a text block follows the same identification rules as a normal section header, but is wrapped with double brackets.\n\n```ini\n[[mytext:text_id]]\nline 1\nanother line\n# comments are ignored\n\nblank line above is captured\n```\n\n### Default and override rules\n\nDefault and override values may be specified with a \"section specification\" in the section header.\n\nSection header rules are specified as `<name>:<id>:<label>`, with all these being optional. When multiple are specified, all must be true. When none are specified, all sections match.\n\nFor example: `[*default:$mycl::mylabel]` will provide default values for all sections that start with \"mycl\" and have the label \"mylabel\".\n\nFor example: `[*override::myid]` will provide override values for all sections with the id \"myid\".\n\n- A property need not exist in a target section for the property to be added by a default or override rule\n- When a property is found in multiple default or override sections, the first to appear will take priority\n- A \"*level\" property may be added to a default or override section to set the priority level\n - The default priority is 0\n - Lower levels take priority\n - Priorities may be negative\n\n```ini\n[*default:MySection]\nOne=Bananas\nTwo=Strawberries\nThree=Peaches\n\n[MySection]\nOne=Red\nTwo=Blue\n\n[*default:MySection]\nThree=Black\n\n[*override:MySection]\nTwo=Violet\n\n[*override:MySection]\n*level=-1\nTwo=Pink\n\n# [=>MySection.One] is \"Red\"\n# [=>MySection.Two] is \"Pink\"\n# [=>MySection.Three] is \"Peaches\"\n```\n",
"bugtrack_url": null,
"license": null,
"summary": "m9 ini configuration",
"version": "1.0.1",
"project_urls": {
"Homepage": "https://github.com/MarcusNyne/m9ini"
},
"split_keywords": [
"ini",
" configuration",
" config",
" settings",
" parse",
" load",
" batch"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "33bee1d23b9619f573e4d82f01e3bcff20c7ce0fec41dfa8e36ffa2ef5b16026",
"md5": "8e40631328bbd71b89745720727b50f0",
"sha256": "45098795482dd8a39297e1cf3d3a45619f9d23933d0594d775bfb7aee1029e58"
},
"downloads": -1,
"filename": "m9ini-1.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "8e40631328bbd71b89745720727b50f0",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10.6",
"size": 31892,
"upload_time": "2025-07-11T21:21:23",
"upload_time_iso_8601": "2025-07-11T21:21:23.957880Z",
"url": "https://files.pythonhosted.org/packages/33/be/e1d23b9619f573e4d82f01e3bcff20c7ce0fec41dfa8e36ffa2ef5b16026/m9ini-1.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "9767f8ac7081085dbffee2d2f20b890f1decae591c1f2fda721ba3585a479c15",
"md5": "167665ed6c5edae1245b703c77a2ef3a",
"sha256": "e1cb8c236312e7fbd832e99375a80d7d7fdf0258512f64791b4f4feb204be3a6"
},
"downloads": -1,
"filename": "m9ini-1.0.1.tar.gz",
"has_sig": false,
"md5_digest": "167665ed6c5edae1245b703c77a2ef3a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10.6",
"size": 67272,
"upload_time": "2025-07-11T21:21:25",
"upload_time_iso_8601": "2025-07-11T21:21:25.504769Z",
"url": "https://files.pythonhosted.org/packages/97/67/f8ac7081085dbffee2d2f20b890f1decae591c1f2fda721ba3585a479c15/m9ini-1.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-11 21:21:25",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "MarcusNyne",
"github_project": "m9ini",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "m9ini"
}