Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

yini-parser-python

The official Python parser for YINI, a configuration format inspired by INI. YINI supports nested sections, comments, and values such as numbers, booleans, lists, and objects. Section markers define the nesting, so indentation is optional.

YINI Test Suite PyPI version Python versions

Requires Python 3.10 or newer. This parser is a release candidate and targets YINI Specification 1.0.0 RC7. See the changelog for release details.


Installation

Install from PyPI, allowing prerelease versions:

python -m pip install --pre yini-parser

The --pre option lets pip select release candidates and other prereleases. To upgrade an existing installation, add --upgrade.

The package name is yini-parser; the Python import name is yini_parser:

import yini_parser

Quick start

Save this configuration as config.yini:

// A small, practical YINI config.

// The App section starts here.
^ App
name = "Demo App"
version = 1.2
features = ["search", "logs"]
debug = false    // off/no would work too.
pageSize = 25

    // Nested under App. Indentation is optional and used for readability.
    ^^ Server
    host = "localhost"
    port = 8080    # YINI also supports # comments.
    useTLS = off

Load it in Python:

from yini_parser import load

data = load("config.yini")

print(data["App"]["name"])  # Demo App
print(data["App"]["Server"]["port"])  # 8080

The result is a Python dictionary. Here is the same data shown as JSON:

{
  "App": {
    "name": "Demo App",
    "version": 1.2,
    "features": ["search", "logs"],
    "debug": false,
    "pageSize": 25,
    "Server": {
      "host": "localhost",
      "port": 8080,
      "useTLS": false
    }
  }
}

To parse text directly, use loads:

from yini_parser import loads

data = loads("""
^ App
name = "Demo App"
version = 1.2
debug = false
""")

print(data["App"]["name"])  # Demo App

API

Function Input Result
load(path, strict=False) A UTF-8 file, given as a string path or pathlib.Path. A Python dictionary.
loads(text, strict=False) A string containing YINI text. A Python dictionary.

Sections and inline objects become dictionaries. Lists become Python lists; strings, numbers, and booleans become the corresponding Python types. YINI null becomes None.

Invalid YINI raises YiniParseError. Catch it to report a parse error:

from yini_parser import YiniParseError, load

try:
    data = load("config.yini")
except YiniParseError as error:
    print(f"Could not parse config.yini: {error}")

The error message includes a line and column when available. File access and UTF-8 decoding errors use Python's standard exceptions.

Strict and lenient parsing

Both functions use lenient mode by default. Pass strict=True to apply the strict rules. A strict document needs exactly one top-level section and a final /END marker:

from yini_parser import loads

data = loads('^ App\nname = "Demo App"\n/END\n', strict=True)

Some common differences are:

Rule Lenient mode Strict mode
/END marker Optional. Required.
Members outside an explicit section Allowed at the document root. Rejected.
Empty member value after = Becomes None with a warning. Rejected.
Duplicate key Keeps the first value and warns. Rejected.
Trailing comma in a list or inline object Allowed. Rejected.
Inline object separator : or =. : only.

An explicit @yini strict declaration is rejected in lenient mode. An @yini lenient declaration produces a warning in strict mode, and all strict validation rules still apply. Duplicate sections under the same parent are errors in both modes. A declaration does not switch the parser's mode.

Warnings use Python's standard warnings system and the YiniParseWarning category, available from yini_parser.api. Mixed line endings and a shebang (#!) outside the start of the first line produce warnings in lenient mode and errors in strict mode. The @include directive is reserved and is rejected in both modes.

The deprecated % binary prefix remains valid in both modes and produces a warning recommending 0b instead.

Inside backticked keys and section names, write \\ for one literal backslash.

See the YINI specification and documentation.


Examples

This repository includes three runnable examples in examples/.

Each Python script reads a .yini file beside it, so you can compare the input with the code that loads it.

After cloning this repository, install the package locally:

python -m pip install -e .

Then run the examples from the repository root:

python examples/example1.py
python examples/example2.py
python examples/example3.py

What they show:

  • example1.py reads basic.yini and prints basic app settings.
  • example2.py reads nested.yini and shows nested sections as dictionaries.
  • example3.py reads application.yini, checks required fields, and prints a configuration report.

More YINI syntax examples are available on the YINI examples page.

Runnable example projects are available in the YINI demo apps repository:


Why YINI?

YINI is designed for configuration files that people read and edit by hand.

Compared with common configuration formats:

  • INI: YINI defines nested sections and value types such as numbers and lists.
  • JSON: YINI supports comments and does not require quotes around simple keys.
  • YAML: YINI does not use indentation to define structure.
  • TOML: YINI uses explicit section markers for hierarchy instead of dotted table names.
Compare the same configuration in YINI, JSON, YAML, and TOML

YINI

^ Application
name = 'demo'
environment = 'dev'

^^ Server
host = 'localhost'
ports = [8080, 8081]

^^^ TLS
enabled = true
mode = 'optional'
  • Application contains the top-level application settings.
  • Server is nested under Application.
  • TLS is nested under Server.
  • Section markers ^ define the nesting. Indentation is optional.
  • Strings can use either ' or ".
  • E/e strings interpret escapes such as \n; C/c remain valid, deprecated aliases.
  • command""" starts a multiline literal that removes structural indentation and preserves line breaks.
  • Source line endings in triple-quoted and command strings become LF (\n) in both modes. Characters produced by escape sequences retain their exact values.

JSON

{
  "Application": {
    "name": "demo",
    "environment": "dev",
    "Server": {
      "host": "localhost",
      "ports": [8080, 8081],
      "TLS": {
        "enabled": true,
        "mode": "optional"
      }
    }
  }
}

YAML

Application:
  name: demo
  environment: dev
  Server:
    host: localhost
    ports:
      - 8080
      - 8081
    TLS:
      enabled: true
      mode: optional

TOML

[Application]
name = "demo"
environment = "dev"

[Application.Server]
host = "localhost"
ports = [8080, 8081]

[Application.Server.TLS]
enabled = true
mode = "optional"

The format and parser are release candidates. Pin the package version and test your application's configuration files before using it in production. If your tools already require JSON, YAML, or TOML, using that format may be a better fit.


Parser implementation

The package includes Python parser code generated by ANTLR, a tool that turns grammar rules into parser code. You only need Python to use the package. Java and the ANTLR generator are needed only by maintainers who regenerate the parser.


Feedback and bug reports

If you find a problem, open an issue on GitHub.

When reporting parser behavior, it is helpful to include:

  • The YINI input that caused the issue.
  • The expected result.
  • The actual result or error message.
  • The installed yini-parser version.
  • The Python version used.
  • Whether you used strict or lenient mode.

Development

From a local checkout, install the development dependencies:

python -m pip install -e ".[dev]"

If you use Task, the equivalent command is:

task install-dev

Run the full project check:

task check

This runs:

  • The test suite with warnings treated as errors.
  • Ruff lint checks.
  • Ruff formatting checks.
  • mypy type checking.

You can also run the tests directly:

python -m pytest -v -W error

The generated parser is included, so normal development does not need Java. Grammar updates are maintained separately; task antlr is a maintainer task that requires Windows, Java, and the vendored ANTLR JAR.

See Development setup and the Maintainer guide for more details.


Testing and stability

The local tests cover the loading API, values, nested sections, strict and lenient rules, warnings, and error handling.

The parser also passes all 542 cases in yini-test-suite 0.4.0rc1, the shared test suite for YINI Specification 1.0.0 RC7. These tests check both strict and lenient parsing. CI runs this pinned suite on pull requests and pushes to main, and before publishing a release.

Passing these tests helps check compatibility with the specification. Test the configuration files your application uses as well.


License

Licensed under Apache License 2.0.


^YINI ≡

YINI is a human-readable, INI-inspired, indentation-insensitive configuration format with clear nested sections, explicit structure, and predictable parsing.

It has a formal specification and a defined grammar.

yini-lang.org · YINI-lang on GitHub

Metadata

Release files for yini-parser 1.0.0rc2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for yini-parser 1.0.0rc2
File Size Uploaded Provenance Actions
yini_parser-1.0.0rc2.tar.gz 50.5 kB Without provenance Details for yini_parser-1.0.0rc2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for yini-parser 1.0.0rc2
File Interpreter ABI Platform Actions
yini_parser-1.0.0rc2-py3-none-any.whl Python 3 none any Details for yini_parser-1.0.0rc2-py3-none-any.whl

Total release size: 100.1 kB

Release files / yini_parser-1.0.0rc2.tar.gz

Download URL yini_parser-1.0.0rc2.tar.gz
Size 50.5 kB
Tags Source
SHA-256 checksum
How to use checksums
c822ad53e73f65fbc3da29a3f8b6aa6c65b54c7f62307c652cea0fdb7ccf56dd
BLAKE2b-256 checksum
How to use checksums
9c52b4977531ecf9842847c6857e746c1f83f7b72635131890bb63cc57b891ba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.0

Release files / yini_parser-1.0.0rc2-py3-none-any.whl

Download URL yini_parser-1.0.0rc2-py3-none-any.whl
Size 49.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e62f17e420ec102d24ea717d5db50a5fd1532ce997dc141005224c0acf2e8b38
BLAKE2b-256 checksum
How to use checksums
101d9f34277118ccda6eaa5e4c72842704dc6c74ca4d9417723932de6edf4f1e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.0

Security for yini-parser 1.0.0rc2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page