]>
Commit | Line | Data |
---|---|---|
1 | Metadata-Version: 2.1 | |
2 | Name: tomli | |
3 | Version: 2.0.1 | |
4 | Summary: A lil' TOML parser | |
5 | Keywords: toml | |
6 | Author-email: Taneli Hukkinen <hukkin@users.noreply.github.com> | |
7 | Requires-Python: >=3.7 | |
8 | Description-Content-Type: text/markdown | |
9 | Classifier: License :: OSI Approved :: MIT License | |
10 | Classifier: Operating System :: MacOS | |
11 | Classifier: Operating System :: Microsoft :: Windows | |
12 | Classifier: Operating System :: POSIX :: Linux | |
13 | Classifier: Programming Language :: Python :: 3 :: Only | |
14 | Classifier: Programming Language :: Python :: 3.7 | |
15 | Classifier: Programming Language :: Python :: 3.8 | |
16 | Classifier: Programming Language :: Python :: 3.9 | |
17 | Classifier: Programming Language :: Python :: 3.10 | |
18 | Classifier: Programming Language :: Python :: Implementation :: CPython | |
19 | Classifier: Programming Language :: Python :: Implementation :: PyPy | |
20 | Classifier: Topic :: Software Development :: Libraries :: Python Modules | |
21 | Classifier: Typing :: Typed | |
22 | Project-URL: Changelog, https://github.com/hukkin/tomli/blob/master/CHANGELOG.md | |
23 | Project-URL: Homepage, https://github.com/hukkin/tomli | |
24 | ||
25 | [![Build Status](https://github.com/hukkin/tomli/workflows/Tests/badge.svg?branch=master)](https://github.com/hukkin/tomli/actions?query=workflow%3ATests+branch%3Amaster+event%3Apush) | |
26 | [![codecov.io](https://codecov.io/gh/hukkin/tomli/branch/master/graph/badge.svg)](https://codecov.io/gh/hukkin/tomli) | |
27 | [![PyPI version](https://img.shields.io/pypi/v/tomli)](https://pypi.org/project/tomli) | |
28 | ||
29 | # Tomli | |
30 | ||
31 | > A lil' TOML parser | |
32 | ||
33 | **Table of Contents** *generated with [mdformat-toc](https://github.com/hukkin/mdformat-toc)* | |
34 | ||
35 | <!-- mdformat-toc start --slug=github --maxlevel=6 --minlevel=2 --> | |
36 | ||
37 | - [Intro](#intro) | |
38 | - [Installation](#installation) | |
39 | - [Usage](#usage) | |
40 | - [Parse a TOML string](#parse-a-toml-string) | |
41 | - [Parse a TOML file](#parse-a-toml-file) | |
42 | - [Handle invalid TOML](#handle-invalid-toml) | |
43 | - [Construct `decimal.Decimal`s from TOML floats](#construct-decimaldecimals-from-toml-floats) | |
44 | - [FAQ](#faq) | |
45 | - [Why this parser?](#why-this-parser) | |
46 | - [Is comment preserving round-trip parsing supported?](#is-comment-preserving-round-trip-parsing-supported) | |
47 | - [Is there a `dumps`, `write` or `encode` function?](#is-there-a-dumps-write-or-encode-function) | |
48 | - [How do TOML types map into Python types?](#how-do-toml-types-map-into-python-types) | |
49 | - [Performance](#performance) | |
50 | ||
51 | <!-- mdformat-toc end --> | |
52 | ||
53 | ## Intro<a name="intro"></a> | |
54 | ||
55 | Tomli is a Python library for parsing [TOML](https://toml.io). | |
56 | Tomli is fully compatible with [TOML v1.0.0](https://toml.io/en/v1.0.0). | |
57 | ||
58 | ## Installation<a name="installation"></a> | |
59 | ||
60 | ```bash | |
61 | pip install tomli | |
62 | ``` | |
63 | ||
64 | ## Usage<a name="usage"></a> | |
65 | ||
66 | ### Parse a TOML string<a name="parse-a-toml-string"></a> | |
67 | ||
68 | ```python | |
69 | import tomli | |
70 | ||
71 | toml_str = """ | |
72 | gretzky = 99 | |
73 | ||
74 | [kurri] | |
75 | jari = 17 | |
76 | """ | |
77 | ||
78 | toml_dict = tomli.loads(toml_str) | |
79 | assert toml_dict == {"gretzky": 99, "kurri": {"jari": 17}} | |
80 | ``` | |
81 | ||
82 | ### Parse a TOML file<a name="parse-a-toml-file"></a> | |
83 | ||
84 | ```python | |
85 | import tomli | |
86 | ||
87 | with open("path_to_file/conf.toml", "rb") as f: | |
88 | toml_dict = tomli.load(f) | |
89 | ``` | |
90 | ||
91 | The file must be opened in binary mode (with the `"rb"` flag). | |
92 | Binary mode will enforce decoding the file as UTF-8 with universal newlines disabled, | |
93 | both of which are required to correctly parse TOML. | |
94 | ||
95 | ### Handle invalid TOML<a name="handle-invalid-toml"></a> | |
96 | ||
97 | ```python | |
98 | import tomli | |
99 | ||
100 | try: | |
101 | toml_dict = tomli.loads("]] this is invalid TOML [[") | |
102 | except tomli.TOMLDecodeError: | |
103 | print("Yep, definitely not valid.") | |
104 | ``` | |
105 | ||
106 | Note that error messages are considered informational only. | |
107 | They should not be assumed to stay constant across Tomli versions. | |
108 | ||
109 | ### Construct `decimal.Decimal`s from TOML floats<a name="construct-decimaldecimals-from-toml-floats"></a> | |
110 | ||
111 | ```python | |
112 | from decimal import Decimal | |
113 | import tomli | |
114 | ||
115 | toml_dict = tomli.loads("precision-matters = 0.982492", parse_float=Decimal) | |
116 | assert toml_dict["precision-matters"] == Decimal("0.982492") | |
117 | ``` | |
118 | ||
119 | Note that `decimal.Decimal` can be replaced with another callable that converts a TOML float from string to a Python type. | |
120 | The `decimal.Decimal` is, however, a practical choice for use cases where float inaccuracies can not be tolerated. | |
121 | ||
122 | Illegal types are `dict` and `list`, and their subtypes. | |
123 | A `ValueError` will be raised if `parse_float` produces illegal types. | |
124 | ||
125 | ## FAQ<a name="faq"></a> | |
126 | ||
127 | ### Why this parser?<a name="why-this-parser"></a> | |
128 | ||
129 | - it's lil' | |
130 | - pure Python with zero dependencies | |
131 | - the fastest pure Python parser [\*](#performance): | |
132 | 15x as fast as [tomlkit](https://pypi.org/project/tomlkit/), | |
133 | 2.4x as fast as [toml](https://pypi.org/project/toml/) | |
134 | - outputs [basic data types](#how-do-toml-types-map-into-python-types) only | |
135 | - 100% spec compliant: passes all tests in | |
136 | [a test set](https://github.com/toml-lang/compliance/pull/8) | |
137 | soon to be merged to the official | |
138 | [compliance tests for TOML](https://github.com/toml-lang/compliance) | |
139 | repository | |
140 | - thoroughly tested: 100% branch coverage | |
141 | ||
142 | ### Is comment preserving round-trip parsing supported?<a name="is-comment-preserving-round-trip-parsing-supported"></a> | |
143 | ||
144 | No. | |
145 | ||
146 | The `tomli.loads` function returns a plain `dict` that is populated with builtin types and types from the standard library only. | |
147 | Preserving comments requires a custom type to be returned so will not be supported, | |
148 | at least not by the `tomli.loads` and `tomli.load` functions. | |
149 | ||
150 | Look into [TOML Kit](https://github.com/sdispater/tomlkit) if preservation of style is what you need. | |
151 | ||
152 | ### Is there a `dumps`, `write` or `encode` function?<a name="is-there-a-dumps-write-or-encode-function"></a> | |
153 | ||
154 | [Tomli-W](https://github.com/hukkin/tomli-w) is the write-only counterpart of Tomli, providing `dump` and `dumps` functions. | |
155 | ||
156 | The core library does not include write capability, as most TOML use cases are read-only, and Tomli intends to be minimal. | |
157 | ||
158 | ### How do TOML types map into Python types?<a name="how-do-toml-types-map-into-python-types"></a> | |
159 | ||
160 | | TOML type | Python type | Details | | |
161 | | ---------------- | ------------------- | ------------------------------------------------------------ | | |
162 | | Document Root | `dict` | | | |
163 | | Key | `str` | | | |
164 | | String | `str` | | | |
165 | | Integer | `int` | | | |
166 | | Float | `float` | | | |
167 | | Boolean | `bool` | | | |
168 | | Offset Date-Time | `datetime.datetime` | `tzinfo` attribute set to an instance of `datetime.timezone` | | |
169 | | Local Date-Time | `datetime.datetime` | `tzinfo` attribute set to `None` | | |
170 | | Local Date | `datetime.date` | | | |
171 | | Local Time | `datetime.time` | | | |
172 | | Array | `list` | | | |
173 | | Table | `dict` | | | |
174 | | Inline Table | `dict` | | | |
175 | ||
176 | ## Performance<a name="performance"></a> | |
177 | ||
178 | The `benchmark/` folder in this repository contains a performance benchmark for comparing the various Python TOML parsers. | |
179 | The benchmark can be run with `tox -e benchmark-pypi`. | |
180 | Running the benchmark on my personal computer output the following: | |
181 | ||
182 | ```console | |
183 | foo@bar:~/dev/tomli$ tox -e benchmark-pypi | |
184 | benchmark-pypi installed: attrs==19.3.0,click==7.1.2,pytomlpp==1.0.2,qtoml==0.3.0,rtoml==0.7.0,toml==0.10.2,tomli==1.1.0,tomlkit==0.7.2 | |
185 | benchmark-pypi run-test-pre: PYTHONHASHSEED='2658546909' | |
186 | benchmark-pypi run-test: commands[0] | python -c 'import datetime; print(datetime.date.today())' | |
187 | 2021-07-23 | |
188 | benchmark-pypi run-test: commands[1] | python --version | |
189 | Python 3.8.10 | |
190 | benchmark-pypi run-test: commands[2] | python benchmark/run.py | |
191 | Parsing data.toml 5000 times: | |
192 | ------------------------------------------------------ | |
193 | parser | exec time | performance (more is better) | |
194 | -----------+------------+----------------------------- | |
195 | rtoml | 0.901 s | baseline (100%) | |
196 | pytomlpp | 1.08 s | 83.15% | |
197 | tomli | 3.89 s | 23.15% | |
198 | toml | 9.36 s | 9.63% | |
199 | qtoml | 11.5 s | 7.82% | |
200 | tomlkit | 56.8 s | 1.59% | |
201 | ``` | |
202 | ||
203 | The parsers are ordered from fastest to slowest, using the fastest parser as baseline. | |
204 | Tomli performed the best out of all pure Python TOML parsers, | |
205 | losing only to pytomlpp (wraps C++) and rtoml (wraps Rust). | |
206 |