Skip to content

tomllib Module

The tomllib module parses TOML (Tom's Obvious, Minimal Language) files. Available in Python 3.11+.

Complexity Reference

Operation Time Space Notes
loads() O(n) O(n) n = string length; parses entire content
load() O(n) O(n) n = file size; reads entire file

Basic Parsing

Load from String

import tomllib

# Parse TOML string - O(n)
toml_string = """
[database]
server = "192.168.1.1"
ports = [8001, 8001, 8002]
enabled = true
"""

config = tomllib.loads(toml_string)
print(config['database']['server'])  # "192.168.1.1"

Load from File

import tomllib

# Parse from file - O(n)
with open("config.toml", "rb") as f:
    config = tomllib.load(f)
    # config is a dict
    print(config)

TOML Data Types

Supported Types

import tomllib

toml_data = """
# String
name = "John Doe"

# Integer
age = 30

# Float
height = 5.9

# Boolean
active = true

# DateTime
created = 2024-01-16T10:30:00Z

# Array
tags = ["python", "toml", "config"]

# Table (dict)
[address]
street = "123 Main St"
city = "Springfield"

# Array of tables
[[users]]
name = "Alice"
age = 25

[[users]]
name = "Bob"
age = 30
"""

config = tomllib.loads(toml_data)  # O(n) in the text length
# config is a dict with nested structures. Parsing is one pass, but nesting
# is not free: each table header creates and installs a dict, so the same
# number of keys spread over tables costs about twice what flat keys do

Working with Configuration Files

Typical Config Structure

# pyproject.toml example
[project]
name = "myapp"
version = "1.0.0"
description = "My application"

[tool.myapp]
include = ["src", "tests"]
verbose = false

Parse Configuration

import tomllib

# Read project config - O(n)
with open("pyproject.toml", "rb") as f:
    pyproject = tomllib.load(f)

# Access nested data
project_name = pyproject['project']['name']
include_paths = pyproject['tool']['myapp']['include']
verbose = pyproject['tool']['myapp']['verbose']

Common Patterns

Application Configuration

import tomllib
from pathlib import Path

def load_config(config_file="config.toml"):
    # O(n) where n = file size
    config_path = Path(config_file)
    if not config_path.exists():
        raise FileNotFoundError(f"{config_file} not found")

    with open(config_path, "rb") as f:
        return tomllib.load(f)

config = load_config()
db_url = config['database']['url']
debug = config['server']['debug']

Merging Defaults

import tomllib

def load_config_with_defaults(user_config_file, defaults):
    # O(n) where n = file size
    defaults_copy = defaults.copy()

    try:
        with open(user_config_file, "rb") as f:
            user_config = tomllib.load(f)
            defaults_copy.update(user_config)
    except FileNotFoundError:
        pass  # Use defaults

    return defaults_copy

# Usage
defaults = {
    'port': 8000,
    'debug': False,
    'workers': 4
}

config = load_config_with_defaults("app.toml", defaults)

Environment-Specific Config

import tomllib
from pathlib import Path

def load_env_config(env="development"):
    # O(n) per config file
    base_config = {}

    # Load base config
    with open("config.toml", "rb") as f:
        base_config.update(tomllib.load(f))

    # Load environment-specific
    env_file = f"config.{env}.toml"
    if Path(env_file).exists():
        with open(env_file, "rb") as f:
            base_config.update(tomllib.load(f))

    return base_config

# Load for current environment
prod_config = load_env_config("production")
dev_config = load_env_config("development")

Limitations

Read-Only

import tomllib

# ❌ Cannot write TOML with tomllib
# tomllib only reads - it's not designed for writing

Python Version

tomllib is available in Python 3.11 and later.