Python tomllib: Read pyproject.toml Files
python tomllib read pyproject toml: Learn how to use Python's tomllib module to read pyproject.toml files, handle TOML data types, manage errors, and access project me...
python tomllib read pyproject toml requires a clear understanding of the core syntax, runtime behavior, and practical implementation patterns demonstrated in the examples below.
Python's tomllib module, introduced in Python 3.11, provides a standard way to parse TOML files. Since pyproject.toml is the canonical configuration file for Python packaging and project metadata, knowing how to read it with tomllib is a practical skill for tooling, scripts, and build automation. This article shows you how to use tomllib to read pyproject.toml, handle the data structures it returns, and avoid common mistakes.
Why tomllib Matters for pyproject.toml
Before Python 3.11, parsing TOML required third-party libraries like tomli or toml. Now tomllib is part of the standard library, so you can read pyproject.toml without adding dependencies. This is especially useful for small utilities, CI scripts, or any code that needs to inspect project configuration without pulling in a package manager.
tomllib parses TOML into native Python dictionaries, lists, strings, integers, floats, booleans, and datetimes. The structure of a pyproject.toml file maps directly to nested dictionaries and lists, making it straightforward to access fields like project.name, project.version, or build-system.requires.
Basic Usage: Reading a pyproject.toml File
The core function is tomllib.load(), which takes a binary file object. This is important: tomllib.load() expects bytes, not text. The most common pattern is to open the file in binary mode and pass it directly.
import tomllib with open("pyproject.toml", "rb") as f: data = tomllib.load(f) print(data["project"]["name"])
If you already have the TOML content as a string, use tomllib.loads() instead:
import tomllib toml_str = """ [project] name = "example" version = "1.0.0" """ data = tomllib.loads(toml_str) print(data["project"]["version"])
Both functions return a dict with the same structure as the TOML file. The binary mode requirement exists because TOML is specified as UTF-8, and tomllib handles encoding internally.
Handling TOML Data Types and Nested Structures
TOML supports tables (sections), arrays, inline tables, and scalar types. tomllib converts them to Python types: tables become dict, arrays become list, and scalars map to str, int, float, bool, and datetime.datetime for TOML datetimes.
Consider this pyproject.toml snippet:
[project] name = "demo" dependencies = ["requests>=2.28", "click"] [project.optional-dependencies] test = ["pytest"] [tool.black] line-length = 88
Accessing nested data requires chaining dictionary keys:
import tomllib with open("pyproject.toml", "rb") as f: data = tomllib.load(f) name = data["project"]["name"] deps = data["project"]["dependencies"] line_length = data["tool"]["black"]["line-length"]
Note that TOML keys with hyphens (like line-length) are accessed using the string key, not attribute access. The returned dictionary preserves the exact key names from the file.
Arrays of tables are also common in pyproject.toml, for example in [[tool.poetry.source]] or [[tool.mypy.overrides]]. These become lists of dictionaries, which you can iterate over.
Error Handling: When the File Is Invalid or Missing
tomllib raises tomllib.TOMLDecodeError if the file contains invalid TOML syntax. This is a subclass of ValueError, so you can catch it specifically or more broadly.
import tomllib try: with open("pyproject.toml", "rb") as f: data = tomllib.load(f) except FileNotFoundError: print("pyproject.toml not found") except tomllib.TOMLDecodeError as e: print(f"Invalid TOML: {e}")
A common mistake is to open the file in text mode ("r") instead of binary mode ("rb"). tomllib.load() expects a binary file object; passing a text file object raises a TypeError. If you need to read from a text stream, use tomllib.loads() with the string content.
Another edge case: pyproject.toml may not exist when you run a script from a subdirectory. Always check the path or catch FileNotFoundError if the file is optional.
Reading pyproject.toml in Different Python Versions
tomllib is only available in Python 3.11 and later. If your code must run on Python 3.10 or earlier, you can use the tomli backport, which has the same API. A common pattern is to try importing tomllib and fall back to tomli:
try: import tomllib except ModuleNotFoundError: import tomli as tomllib
This lets you write code that works across Python versions. The backport tomli is a drop-in replacement for reading TOML; it does not support writing, just like tomllib.
When you control the runtime environment, you can simply require Python 3.11+ and use tomllib directly. For libraries that need broader compatibility, the fallback approach is standard.
Practical Patterns for Accessing Project Metadata
A common use case is reading the project name and version to display or validate it. Since pyproject.toml follows the PEP 621 specification, the [project] table contains standardized fields.
import tomllib def get_project_version(path="pyproject.toml"): with open(path, "rb") as f: data = tomllib.load(f) return data.get("project", {}).get("version")
Using .get() with defaults prevents KeyError when fields are missing. This is useful when you want to gracefully handle incomplete configuration files.
Another pattern is to combine tomllib with pathlib for cleaner path handling:
from pathlib import Path import tomllib pyproject = Path("pyproject.toml") if pyproject.exists(): with pyproject.open("rb") as f: data = tomllib.load(f)
This avoids manual string concatenation and makes the code more portable.
Common Pitfalls When Using tomllib
One frequent mistake is expecting tomllib.load() to accept a file path as a string. It does not; it requires a file object. Always use open() or Path.open().
Another pitfall is assuming that TOML keys are case-insensitive or that hyphens are converted to underscores. Neither is true. tomllib preserves keys exactly as written. If you need to access a key with a hyphen, use the exact string.
Also, be aware that tomllib does not support writing TOML. It is a read-only parser. If you need to modify and write back a pyproject.toml, you'll need a library like tomlkit or tomli-w. This is a deliberate design choice; the standard library only handles parsing.
Finally, remember that tomllib parses the entire file into memory. For typical pyproject.toml files, this is negligible. But if you are processing many large TOML files in a loop, consider streaming or limiting the file size to avoid memory pressure.
When you need to read pyproject.toml in a Python script, tomllib gives you a clean, dependency-free way to access project configuration. Its strict TOML compliance and native type mapping make it the right choice for modern Python tooling.