Pyjo.INI - INI loader and dumper¶
from Pyjo.INI import dump, load
config = load('[default]\nregion = eu-central-1\noutput = json\n')
string = dump({'www': {'listen': '127.0.0.1:9000', 'pm': 'static', 'pm.max_children': 2}})
Pyjo.INI loads and dumps the INI files that well-known programs read
and write, as ~/.aws/config and ~/.aws/credentials, php.ini and
php-fpm.conf, .editorconfig and my.cnf, the format of
Pyjoyment.Plugin.INIConfig. Its syntax is the one of
configparser of the standard library, which botocore reads
~/.aws/config with, and what PHP and the others need besides.
A line [section] starts a section, whose name is kept as it is, as
[profile dev], and a section that comes again adds its keys. A line
key = value or key: value sets a key, at the first delimiter of the
line, with the case of the key kept, and a line without a delimiter is a key
of the value None, as skip-name-resolve of my.cnf. The keys
before the first section are at the top of the dict, as root = true of
.editorconfig. A line that starts with ; or # is a comment, and
there are no comments after a value, as in configparser.
# {'root': 'true', '*.py': {'indent_size': '4'}}
load('root = true\n\n[*.py]\nindent_size = 4\n')
The comments are left out, or kept with comments, each line a key of the
value None, in the order of the file, which dump() writes as it is,
so that a file that is changed keeps them. The key is a Comment, a
string that counts the same comments before it in its dict, so that a
comment that comes again is a key of its own.
# {Comment('; the region', 0): None, 'region': 'eu-central-1'}
load('; the region\nregion = eu-central-1\n', comments=True)
A value is a string. A line indented more than its key continues its value,
whose lines are joined with \n, and a blank line ends it. An empty value
whose lines are all key = value is a dict, as the nested settings of
~/.aws/config, and a key that comes again in a section is a list of its
values, in their order, as extension of php.ini.
# {'profile dev': {'s3': {'max_concurrent_requests': '20'}}}
load('[profile dev]\ns3 =\n max_concurrent_requests = 20\n')
# {'PHP': {'extension': ['curl', 'mbstring']}}
load('[PHP]\nextension = curl\nextension = mbstring\n')
dump() writes the same: the keys at the top first, then the sections, a
dict of a dict, a list as its key again for each of its values, a dict in a
section as an indented block, None as a key alone, a key that starts with
; or # of the value None as a comment, and True and False as
true and false. A key is never quoted, as php-fpm takes a key with a
dot, as pm.max_children, only as it is.
# '[default]\nregion = eu-central-1\n'
dump({'default': {'region': 'eu-central-1'}})
# '[www]\n; the workers\npm.max_children = 2\n'
dump({'www': {'; the workers': None, 'pm.max_children': 2}})
What INI cannot hold raises an error: a dict deeper than a dict in a section,
a list in a list, an empty list, a value with spaces at the ends of a line,
an empty line in a value, a line of a value that would be a comment, and a
key or the name of a section that the loader would read otherwise. Another
object is what Pyjo.JSON encodes, the value of its method
__json__ or its string.
See also¶
Pyjoyment.Plugin.INIConfig, Pyjo.TOML, https://mojolicious.org.
- class Pyjo.INI.Comment(line: str, occurrence: int = 0)[source]¶
comment = Comment('; the region') comment = Comment('#', 1)
A line of a comment, the key of the value
Nonethatload()gives withcomments, withoccurrence, the number of the same comments before it in its dict, so that two of them are two keys. It equals only aCommentof the same line and occurrence.# {Comment('#', 0): None, Comment('#', 1): None} load('#\n#\n', comments=True)
- Pyjo.INI.dump(value: Any, *, sort_keys: bool = False) str[source]¶
string = dump(value) string = dump(value, sort_keys=True)
Dump a dict to an INI string, with the keys of a dict in the order of the
dict, or sorted withsort_keys.# 'listen = 127.0.0.1:9000\npm.max_children = 2\n' dump({'listen': '127.0.0.1:9000', 'pm.max_children': 2})
- Pyjo.INI.load(string: str | bytes | bytearray, *, comments: bool = False, unquote: bool = False) dict[str, Any][source]¶
value = load(string) value = load(string, comments=True) value = load(string, unquote=True)
Load an INI string, whose error is a
Pyjo.Exception, without its comments, or with them withcomments, and with the quotes around a value kept, asconfigparserkeeps them, or taken off withunquote, as PHP does.# {'PHP': {'error_log': '"/var/log/php.log"'}} load('[PHP]\nerror_log = "/var/log/php.log"\n') # {'PHP': {'error_log': '/var/log/php.log'}} load('[PHP]\nerror_log = "/var/log/php.log"\n', unquote=True)
A byte order mark at the start of the string, which an editor on Windows writes, is not a part of its first line. Bytes are
UTF-8, orUTF-16orUTF-32with a byte order mark, as Windows PowerShell writesUTF-16LE.# {'default': {'region': 'eu-central-1'}} load('[default]\nregion = eu-central-1\n'.encode('UTF-16'))