Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 1 | .. highlightlang:: cfg |
| 2 | |
Éric Araujo | 0300b5c | 2011-06-06 01:54:54 +0200 | [diff] [blame] | 3 | .. _setupcfg-spec: |
Éric Araujo | 823759e | 2011-06-04 18:46:25 +0200 | [diff] [blame] | 4 | |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 5 | ******************************************* |
| 6 | Specification of the :file:`setup.cfg` file |
| 7 | ******************************************* |
| 8 | |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 9 | :version: 0.9 |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 10 | |
| 11 | This document describes the :file:`setup.cfg`, an ini-style configuration file |
Éric Araujo | ed4fd70 | 2011-06-06 02:07:24 +0200 | [diff] [blame] | 12 | used by Packaging to replace the :file:`setup.py` file used by Distutils. |
| 13 | This specification is language-agnostic, and will therefore repeat some |
| 14 | information that's already documented for Python in the |
| 15 | :class:`configparser.RawConfigParser` documentation. |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 16 | |
Éric Araujo | f0f9b22 | 2011-06-06 01:52:37 +0200 | [diff] [blame] | 17 | .. contents:: |
| 18 | :depth: 3 |
| 19 | :local: |
| 20 | |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 21 | |
Éric Araujo | 79d9c42 | 2011-10-19 08:41:07 +0200 | [diff] [blame] | 22 | .. _setupcfg-syntax: |
| 23 | |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 24 | Syntax |
| 25 | ====== |
| 26 | |
Éric Araujo | ed4fd70 | 2011-06-06 02:07:24 +0200 | [diff] [blame] | 27 | The ini-style format used in the configuration file is a simple collection of |
| 28 | sections that group sets of key-value fields separated by ``=`` or ``:`` and |
| 29 | optional whitespace. Lines starting with ``#`` or ``;`` are comments and will |
| 30 | be ignored. Empty lines are also ignored. Example:: |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 31 | |
| 32 | [section1] |
| 33 | # comment |
| 34 | name = value |
| 35 | name2 = "other value" |
| 36 | |
| 37 | [section2] |
| 38 | foo = bar |
| 39 | |
| 40 | |
Éric Araujo | ed4fd70 | 2011-06-06 02:07:24 +0200 | [diff] [blame] | 41 | Parsing values |
| 42 | --------------- |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 43 | |
Éric Araujo | ed4fd70 | 2011-06-06 02:07:24 +0200 | [diff] [blame] | 44 | Here are a set of rules to parse values: |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 45 | |
Éric Araujo | ed4fd70 | 2011-06-06 02:07:24 +0200 | [diff] [blame] | 46 | - If a value is quoted with ``"`` chars, it's a string. If a quote character is |
| 47 | present in the quoted value, it can be escaped as ``\"`` or left as-is. |
| 48 | |
| 49 | - If the value is ``true``, ``t``, ``yes``, ``y`` (case-insensitive) or ``1``, |
| 50 | it's converted to the language equivalent of a ``True`` value; if it's |
| 51 | ``false``, ``f``, ``no``, ``n`` (case-insensitive) or ``0``, it's converted to |
| 52 | the equivalent of ``False``. |
| 53 | |
| 54 | - A value can contain multiple lines. When read, lines are converted into a |
| 55 | sequence of values. Each line after the first must start with a least one |
| 56 | space or tab character; this leading indentation will be stripped. |
| 57 | |
| 58 | - All other values are considered strings. |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 59 | |
| 60 | Examples:: |
| 61 | |
| 62 | [section] |
| 63 | foo = one |
| 64 | two |
| 65 | three |
| 66 | |
| 67 | bar = false |
| 68 | baz = 1.3 |
| 69 | boo = "ok" |
| 70 | beee = "wqdqw pojpj w\"ddq" |
| 71 | |
| 72 | |
| 73 | Extending files |
| 74 | --------------- |
| 75 | |
Éric Araujo | ed4fd70 | 2011-06-06 02:07:24 +0200 | [diff] [blame] | 76 | A configuration file can be extended (i.e. included) by other files. For this, |
Brett Cannon | 5c9a8d0 | 2011-09-05 21:08:14 -0700 | [diff] [blame] | 77 | a ``DEFAULT`` section must contain an ``extends`` key whose value points to one |
Éric Araujo | ed4fd70 | 2011-06-06 02:07:24 +0200 | [diff] [blame] | 78 | or more files which will be merged into the current files by adding new sections |
| 79 | and fields. If a file loaded by ``extends`` contains sections or keys that |
| 80 | already exist in the original file, they will not override the previous values. |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 81 | |
Éric Araujo | 1389008 | 2011-06-06 01:58:25 +0200 | [diff] [blame] | 82 | Contents of :file:`one.cfg`:: |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 83 | |
| 84 | [section1] |
Éric Araujo | 1389008 | 2011-06-06 01:58:25 +0200 | [diff] [blame] | 85 | name = value |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 86 | |
| 87 | [section2] |
Éric Araujo | 1389008 | 2011-06-06 01:58:25 +0200 | [diff] [blame] | 88 | foo = foo from one.cfg |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 89 | |
Éric Araujo | 1389008 | 2011-06-06 01:58:25 +0200 | [diff] [blame] | 90 | Contents of :file:`two.cfg`:: |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 91 | |
| 92 | [DEFAULT] |
Éric Araujo | 1389008 | 2011-06-06 01:58:25 +0200 | [diff] [blame] | 93 | extends = one.cfg |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 94 | |
| 95 | [section2] |
Éric Araujo | 1389008 | 2011-06-06 01:58:25 +0200 | [diff] [blame] | 96 | foo = foo from two.cfg |
| 97 | baz = baz from two.cfg |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 98 | |
Éric Araujo | 1389008 | 2011-06-06 01:58:25 +0200 | [diff] [blame] | 99 | The result of parsing :file:`two.cfg` is equivalent to this file:: |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 100 | |
| 101 | [section1] |
Éric Araujo | 1389008 | 2011-06-06 01:58:25 +0200 | [diff] [blame] | 102 | name = value |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 103 | |
| 104 | [section2] |
Éric Araujo | 1389008 | 2011-06-06 01:58:25 +0200 | [diff] [blame] | 105 | foo = foo from one.cfg |
| 106 | baz = baz from two.cfg |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 107 | |
Éric Araujo | 1389008 | 2011-06-06 01:58:25 +0200 | [diff] [blame] | 108 | Example use of multi-line notation to include more than one file:: |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 109 | |
| 110 | [DEFAULT] |
Éric Araujo | 1389008 | 2011-06-06 01:58:25 +0200 | [diff] [blame] | 111 | extends = one.cfg |
| 112 | two.cfg |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 113 | |
Éric Araujo | ed4fd70 | 2011-06-06 02:07:24 +0200 | [diff] [blame] | 114 | When several files are provided, they are processed sequentially, following the |
| 115 | precedence rules explained above. This means that the list of files should go |
| 116 | from most specialized to most common. |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 117 | |
Éric Araujo | ed4fd70 | 2011-06-06 02:07:24 +0200 | [diff] [blame] | 118 | **Tools will need to provide a way to produce a merged version of the |
| 119 | file**. This will be useful to let users publish a single file. |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 120 | |
| 121 | |
Éric Araujo | 79d9c42 | 2011-10-19 08:41:07 +0200 | [diff] [blame] | 122 | .. _setupcfg-sections: |
| 123 | |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 124 | Description of sections and fields |
| 125 | ================================== |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 126 | |
| 127 | Each section contains a description of its options. |
| 128 | |
| 129 | - Options that are marked *multi* can have multiple values, one value per |
| 130 | line. |
| 131 | - Options that are marked *optional* can be omitted. |
| 132 | - Options that are marked *environ* can use environment markers, as described |
| 133 | in :PEP:`345`. |
| 134 | |
| 135 | |
| 136 | The sections are: |
| 137 | |
| 138 | global |
| 139 | Global options not related to one command. |
| 140 | |
| 141 | metadata |
| 142 | Name, version and other information defined by :PEP:`345`. |
| 143 | |
| 144 | files |
| 145 | Modules, scripts, data, documentation and other files to include in the |
| 146 | distribution. |
| 147 | |
Éric Araujo | c7f9f2b | 2011-06-09 08:18:17 +0200 | [diff] [blame] | 148 | extension sections |
| 149 | Options used to build extension modules. |
| 150 | |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 151 | command sections |
| 152 | Options given for specific commands, identical to those that can be given |
| 153 | on the command line. |
| 154 | |
| 155 | |
Éric Araujo | 79d9c42 | 2011-10-19 08:41:07 +0200 | [diff] [blame] | 156 | .. _setupcfg-section-global: |
| 157 | |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 158 | Global options |
Éric Araujo | a462a80 | 2011-06-09 08:15:47 +0200 | [diff] [blame] | 159 | -------------- |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 160 | |
| 161 | Contains global options for Packaging. This section is shared with Distutils. |
| 162 | |
| 163 | |
| 164 | commands |
| 165 | Defined Packaging command. A command is defined by its fully |
| 166 | qualified name. *optional*, *multi* |
| 167 | |
| 168 | Examples:: |
| 169 | |
| 170 | [global] |
| 171 | commands = |
| 172 | package.setup.CustomSdistCommand |
| 173 | package.setup.BdistDeb |
| 174 | |
| 175 | compilers |
| 176 | Defined Packaging compiler. A compiler is defined by its fully |
| 177 | qualified name. *optional*, *multi* |
| 178 | |
| 179 | Example:: |
| 180 | |
| 181 | [global] |
| 182 | compilers = |
| 183 | hotcompiler.SmartCCompiler |
| 184 | |
Éric Araujo | 643cb73 | 2011-06-11 00:33:38 +0200 | [diff] [blame] | 185 | setup_hooks |
| 186 | Defines a list of callables to be called right after the :file:`setup.cfg` |
Éric Araujo | 54bb1e6 | 2011-06-19 21:34:16 +0200 | [diff] [blame] | 187 | file is read, before any other processing. Each value is a Python dotted |
| 188 | name to an object, which has to be defined in a module present in the project |
| 189 | directory alonside :file:`setup.cfg` or on Python's :data:`sys.path` (see |
| 190 | :ref:`packaging-finding-hooks`). The callables are executed in the |
Éric Araujo | 643cb73 | 2011-06-11 00:33:38 +0200 | [diff] [blame] | 191 | order they're found in the file; if one of them cannot be found, tools should |
| 192 | not stop, but for example produce a warning and continue with the next line. |
| 193 | Each callable receives the configuration as a dictionary (keys are |
| 194 | :file:`setup.cfg` sections, values are dictionaries of fields) and can make |
Éric Araujo | 54bb1e6 | 2011-06-19 21:34:16 +0200 | [diff] [blame] | 195 | any change to it. *optional*, *multi* |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 196 | |
| 197 | Example:: |
| 198 | |
| 199 | [global] |
Éric Araujo | 54bb1e6 | 2011-06-19 21:34:16 +0200 | [diff] [blame] | 200 | setup_hooks = _setuphooks.customize_config |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 201 | |
| 202 | |
Éric Araujo | 79d9c42 | 2011-10-19 08:41:07 +0200 | [diff] [blame] | 203 | |
| 204 | .. _setupcfg-section-metadata: |
| 205 | |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 206 | Metadata |
Éric Araujo | a462a80 | 2011-06-09 08:15:47 +0200 | [diff] [blame] | 207 | -------- |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 208 | |
| 209 | The metadata section contains the metadata for the project as described in |
| 210 | :PEP:`345`. Field names are case-insensitive. |
| 211 | |
| 212 | Fields: |
| 213 | |
| 214 | name |
| 215 | Name of the project. |
| 216 | |
| 217 | version |
| 218 | Version of the project. Must comply with :PEP:`386`. |
| 219 | |
| 220 | platform |
| 221 | Platform specification describing an operating system |
| 222 | supported by the distribution which is not listed in the "Operating System" |
| 223 | Trove classifiers (:PEP:`301`). *optional*, *multi* |
| 224 | |
| 225 | supported-platform |
| 226 | Binary distributions containing a PKG-INFO file will |
| 227 | use the Supported-Platform field in their metadata to specify the OS and |
| 228 | CPU for which the binary distribution was compiled. The semantics of |
| 229 | the Supported-Platform field are free form. *optional*, *multi* |
| 230 | |
| 231 | summary |
| 232 | A one-line summary of what the distribution does. |
| 233 | (Used to be called *description* in Distutils1.) |
| 234 | |
| 235 | description |
| 236 | A longer description. (Used to be called *long_description* |
| 237 | in Distutils1.) A file can be provided in the *description-file* field. |
| 238 | *optional* |
| 239 | |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 240 | keywords |
| 241 | A list of additional keywords to be used to assist searching |
| 242 | for the distribution in a larger catalog. Comma or space-separated. |
| 243 | *optional* |
| 244 | |
| 245 | home-page |
| 246 | The URL for the distribution's home page. |
| 247 | |
| 248 | download-url |
| 249 | The URL from which this version of the distribution |
| 250 | can be downloaded. *optional* |
| 251 | |
| 252 | author |
| 253 | Author's name. *optional* |
| 254 | |
| 255 | author-email |
| 256 | Author's e-mail. *optional* |
| 257 | |
| 258 | maintainer |
| 259 | Maintainer's name. *optional* |
| 260 | |
| 261 | maintainer-email |
| 262 | Maintainer's e-mail. *optional* |
| 263 | |
| 264 | license |
| 265 | A text indicating the term of uses, when a trove classifier does |
| 266 | not match. *optional*. |
| 267 | |
| 268 | classifiers |
| 269 | Classification for the distribution, as described in PEP 301. |
| 270 | *optional*, *multi*, *environ* |
| 271 | |
| 272 | requires-dist |
| 273 | name of another packaging project required as a dependency. |
| 274 | The format is *name (version)* where version is an optional |
| 275 | version declaration, as described in PEP 345. *optional*, *multi*, *environ* |
| 276 | |
| 277 | provides-dist |
| 278 | name of another packaging project contained within this |
| 279 | distribution. Same format than *requires-dist*. *optional*, *multi*, |
| 280 | *environ* |
| 281 | |
| 282 | obsoletes-dist |
| 283 | name of another packaging project this version obsoletes. |
| 284 | Same format than *requires-dist*. *optional*, *multi*, *environ* |
| 285 | |
| 286 | requires-python |
Éric Araujo | fdeb8bf | 2011-06-06 19:57:02 +0200 | [diff] [blame] | 287 | Specifies the Python version the distribution requires. The value is a |
| 288 | comma-separated list of version predicates, as described in PEP 345. |
| 289 | *optional*, *environ* |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 290 | |
| 291 | requires-externals |
| 292 | a dependency in the system. This field is free-form, |
| 293 | and just a hint for downstream maintainers. *optional*, *multi*, |
| 294 | *environ* |
| 295 | |
| 296 | project-url |
| 297 | A label, followed by a browsable URL for the project. |
| 298 | "label, url". The label is limited to 32 signs. *optional*, *multi* |
| 299 | |
Éric Araujo | 8a4e7a9 | 2011-06-06 01:58:54 +0200 | [diff] [blame] | 300 | One extra field not present in PEP 345 is supported: |
| 301 | |
| 302 | description-file |
| 303 | Path to a text file that will be used to fill the ``description`` field. |
Éric Araujo | 8474f29 | 2011-06-11 00:21:18 +0200 | [diff] [blame] | 304 | Multiple values are accepted; they must be separated by whitespace. |
Éric Araujo | 8a4e7a9 | 2011-06-06 01:58:54 +0200 | [diff] [blame] | 305 | ``description-file`` and ``description`` are mutually exclusive. *optional* |
| 306 | |
| 307 | |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 308 | |
| 309 | Example:: |
| 310 | |
| 311 | [metadata] |
| 312 | name = pypi2rpm |
| 313 | version = 0.1 |
| 314 | author = Tarek Ziadé |
| 315 | author-email = tarek@ziade.org |
| 316 | summary = Script that transforms an sdist archive into a RPM package |
| 317 | description-file = README |
| 318 | home-page = http://bitbucket.org/tarek/pypi2rpm/wiki/Home |
| 319 | project-url: |
| 320 | Repository, http://bitbucket.org/tarek/pypi2rpm/ |
| 321 | RSS feed, https://bitbucket.org/tarek/pypi2rpm/rss |
| 322 | classifier = |
| 323 | Development Status :: 3 - Alpha |
| 324 | License :: OSI Approved :: Mozilla Public License 1.1 (MPL 1.1) |
| 325 | |
| 326 | You should not give any explicit value for metadata-version: it will be guessed |
| 327 | from the fields present in the file. |
| 328 | |
| 329 | |
Éric Araujo | 79d9c42 | 2011-10-19 08:41:07 +0200 | [diff] [blame] | 330 | .. _setupcfg-section-files: |
| 331 | |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 332 | Files |
Éric Araujo | a462a80 | 2011-06-09 08:15:47 +0200 | [diff] [blame] | 333 | ----- |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 334 | |
| 335 | This section describes the files included in the project. |
| 336 | |
| 337 | packages_root |
| 338 | the root directory containing all packages and modules |
Éric Araujo | 79d9c42 | 2011-10-19 08:41:07 +0200 | [diff] [blame] | 339 | (default: current directory, i.e. the project's top-level |
| 340 | directory where :file:`setup.cfg` lives). *optional* |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 341 | |
| 342 | packages |
| 343 | a list of packages the project includes *optional*, *multi* |
| 344 | |
| 345 | modules |
| 346 | a list of packages the project includes *optional*, *multi* |
| 347 | |
| 348 | scripts |
| 349 | a list of scripts the project includes *optional*, *multi* |
| 350 | |
| 351 | extra_files |
Éric Araujo | 79d9c42 | 2011-10-19 08:41:07 +0200 | [diff] [blame] | 352 | a list of patterns for additional files to include in source distributions |
| 353 | (see :ref:`packaging-manifest`) *optional*, *multi* |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 354 | |
| 355 | Example:: |
| 356 | |
| 357 | [files] |
| 358 | packages_root = src |
| 359 | packages = |
| 360 | pypi2rpm |
| 361 | pypi2rpm.command |
| 362 | |
| 363 | scripts = |
| 364 | pypi2rpm/pypi2rpm.py |
| 365 | |
| 366 | extra_files = |
| 367 | setup.py |
| 368 | README |
| 369 | |
| 370 | |
| 371 | .. Note:: |
| 372 | The :file:`setup.cfg` configuration file is included by default. Contrary to |
| 373 | Distutils, :file:`README` (or :file:`README.txt`) and :file:`setup.py` are |
| 374 | not included by default. |
| 375 | |
| 376 | |
| 377 | Resources |
Éric Araujo | a462a80 | 2011-06-09 08:15:47 +0200 | [diff] [blame] | 378 | ^^^^^^^^^ |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 379 | |
| 380 | This section describes the files used by the project which must not be installed |
| 381 | in the same place that python modules or libraries, they are called |
| 382 | **resources**. They are for example documentation files, script files, |
| 383 | databases, etc... |
| 384 | |
| 385 | For declaring resources, you must use this notation:: |
| 386 | |
| 387 | source = destination |
| 388 | |
| 389 | Data-files are declared in the **resources** field in the **file** section, for |
| 390 | example:: |
| 391 | |
| 392 | [files] |
| 393 | resources = |
| 394 | source1 = destination1 |
| 395 | source2 = destination2 |
| 396 | |
| 397 | The **source** part of the declaration are relative paths of resources files |
| 398 | (using unix path separator **/**). For example, if you've this source tree:: |
| 399 | |
| 400 | foo/ |
| 401 | doc/ |
| 402 | doc.man |
| 403 | scripts/ |
| 404 | foo.sh |
| 405 | |
| 406 | Your setup.cfg will look like:: |
| 407 | |
| 408 | [files] |
| 409 | resources = |
| 410 | doc/doc.man = destination_doc |
| 411 | scripts/foo.sh = destination_scripts |
| 412 | |
| 413 | The final paths where files will be placed are composed by : **source** + |
| 414 | **destination**. In the previous example, **doc/doc.man** will be placed in |
| 415 | **destination_doc/doc/doc.man** and **scripts/foo.sh** will be placed in |
| 416 | **destination_scripts/scripts/foo.sh**. (If you want more control on the final |
Éric Araujo | 0300b5c | 2011-06-06 01:54:54 +0200 | [diff] [blame] | 417 | path, take a look at :ref:`setupcfg-resources-base-prefix`). |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 418 | |
| 419 | The **destination** part of resources declaration are paths with categories. |
| 420 | Indeed, it's generally a bad idea to give absolute path as it will be cross |
| 421 | incompatible. So, you must use resources categories in your **destination** |
| 422 | declaration. Categories will be replaced by their real path at the installation |
| 423 | time. Using categories is all benefit, your declaration will be simpler, cross |
| 424 | platform and it will allow packager to place resources files where they want |
| 425 | without breaking your code. |
| 426 | |
| 427 | Categories can be specified by using this syntax:: |
| 428 | |
| 429 | {category} |
| 430 | |
| 431 | Default categories are: |
| 432 | |
| 433 | * config |
| 434 | * appdata |
| 435 | * appdata.arch |
| 436 | * appdata.persistent |
| 437 | * appdata.disposable |
| 438 | * help |
| 439 | * icon |
| 440 | * scripts |
| 441 | * doc |
| 442 | * info |
| 443 | * man |
| 444 | |
| 445 | A special category also exists **{distribution.name}** that will be replaced by |
| 446 | the name of the distribution, but as most of the defaults categories use them, |
| 447 | so it's not necessary to add **{distribution.name}** into your destination. |
| 448 | |
| 449 | If you use categories in your declarations, and you are encouraged to do, final |
| 450 | path will be:: |
| 451 | |
| 452 | source + destination_expanded |
| 453 | |
| 454 | .. _example_final_path: |
| 455 | |
| 456 | For example, if you have this setup.cfg:: |
| 457 | |
| 458 | [metadata] |
| 459 | name = foo |
| 460 | |
| 461 | [files] |
| 462 | resources = |
| 463 | doc/doc.man = {doc} |
| 464 | |
| 465 | And if **{doc}** is replaced by **{datadir}/doc/{distribution.name}**, final |
| 466 | path will be:: |
| 467 | |
| 468 | {datadir}/doc/foo/doc/doc.man |
| 469 | |
| 470 | Where {datafir} category will be platform-dependent. |
| 471 | |
| 472 | |
| 473 | More control on source part |
Éric Araujo | a462a80 | 2011-06-09 08:15:47 +0200 | [diff] [blame] | 474 | """"""""""""""""""""""""""" |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 475 | |
| 476 | Glob syntax |
Éric Araujo | a462a80 | 2011-06-09 08:15:47 +0200 | [diff] [blame] | 477 | ''''''''''' |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 478 | |
| 479 | When you declare source file, you can use a glob-like syntax to match multiples file, for example:: |
| 480 | |
| 481 | scripts/* = {script} |
| 482 | |
| 483 | Will match all the files in the scripts directory and placed them in the script category. |
| 484 | |
| 485 | Glob tokens are: |
| 486 | |
| 487 | * ``*``: match all files. |
| 488 | * ``?``: match any character. |
| 489 | * ``**``: match any level of tree recursion (even 0). |
| 490 | * ``{}``: will match any part separated by comma (example: ``{sh,bat}``). |
| 491 | |
| 492 | .. TODO Add examples |
| 493 | |
| 494 | Order of declaration |
Éric Araujo | a462a80 | 2011-06-09 08:15:47 +0200 | [diff] [blame] | 495 | '''''''''''''''''''' |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 496 | |
| 497 | The order of declaration is important if one file match multiple rules. The last |
| 498 | rules matched by file is used, this is useful if you have this source tree:: |
| 499 | |
| 500 | foo/ |
| 501 | doc/ |
| 502 | index.rst |
| 503 | setup.rst |
| 504 | documentation.txt |
| 505 | doc.tex |
| 506 | README |
| 507 | |
| 508 | And you want all the files in the doc directory to be placed in {doc} category, |
| 509 | but README must be placed in {help} category, instead of listing all the files |
| 510 | one by one, you can declare them in this way:: |
| 511 | |
| 512 | [files] |
| 513 | resources = |
| 514 | doc/* = {doc} |
| 515 | doc/README = {help} |
| 516 | |
| 517 | Exclude |
Éric Araujo | a462a80 | 2011-06-09 08:15:47 +0200 | [diff] [blame] | 518 | ''''''' |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 519 | |
| 520 | You can exclude some files of resources declaration by giving no destination, it |
| 521 | can be useful if you have a non-resources file in the same directory of |
| 522 | resources files:: |
| 523 | |
| 524 | foo/ |
| 525 | doc/ |
| 526 | RELEASES |
| 527 | doc.tex |
| 528 | documentation.txt |
| 529 | docu.rst |
| 530 | |
| 531 | Your **files** section will be:: |
| 532 | |
| 533 | [files] |
| 534 | resources = |
| 535 | doc/* = {doc} |
| 536 | doc/RELEASES = |
| 537 | |
| 538 | More control on destination part |
Éric Araujo | a462a80 | 2011-06-09 08:15:47 +0200 | [diff] [blame] | 539 | """""""""""""""""""""""""""""""" |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 540 | |
Éric Araujo | 0300b5c | 2011-06-06 01:54:54 +0200 | [diff] [blame] | 541 | .. _setupcfg-resources-base-prefix: |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 542 | |
| 543 | Defining a base prefix |
Éric Araujo | a462a80 | 2011-06-09 08:15:47 +0200 | [diff] [blame] | 544 | '''''''''''''''''''''' |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 545 | |
| 546 | When you define your resources, you can have more control of how the final path |
Éric Araujo | 60533e0 | 2011-06-06 02:00:54 +0200 | [diff] [blame] | 547 | is computed. |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 548 | |
| 549 | By default, the final path is:: |
| 550 | |
| 551 | destination + source |
| 552 | |
| 553 | This can generate long paths, for example (example_final_path_):: |
| 554 | |
| 555 | {datadir}/doc/foo/doc/doc.man |
| 556 | |
| 557 | When you declare your source, you can use whitespace to split the source in |
| 558 | **prefix** **suffix**. So, for example, if you have this source:: |
| 559 | |
| 560 | docs/ doc.man |
| 561 | |
| 562 | The **prefix** is "docs/" and the **suffix** is "doc.html". |
| 563 | |
| 564 | .. note:: |
| 565 | |
| 566 | Separator can be placed after a path separator or replace it. So these two |
| 567 | sources are equivalent:: |
| 568 | |
| 569 | docs/ doc.man |
| 570 | docs doc.man |
| 571 | |
| 572 | .. note:: |
| 573 | |
Éric Araujo | 60533e0 | 2011-06-06 02:00:54 +0200 | [diff] [blame] | 574 | Glob syntax is working the same way with standard source and split source. |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 575 | So these rules:: |
| 576 | |
| 577 | docs/* |
| 578 | docs/ * |
| 579 | docs * |
| 580 | |
| 581 | Will match all the files in the docs directory. |
| 582 | |
Éric Araujo | 60533e0 | 2011-06-06 02:00:54 +0200 | [diff] [blame] | 583 | When you use split source, the final path is computed this way:: |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 584 | |
| 585 | destination + prefix |
| 586 | |
| 587 | So for example, if you have this setup.cfg:: |
| 588 | |
| 589 | [metadata] |
| 590 | name = foo |
| 591 | |
| 592 | [files] |
| 593 | resources = |
| 594 | doc/ doc.man = {doc} |
| 595 | |
| 596 | And if **{doc}** is replaced by **{datadir}/doc/{distribution.name}**, final |
| 597 | path will be:: |
| 598 | |
| 599 | {datadir}/doc/foo/doc.man |
| 600 | |
| 601 | |
| 602 | Overwriting paths for categories |
Éric Araujo | a462a80 | 2011-06-09 08:15:47 +0200 | [diff] [blame] | 603 | """""""""""""""""""""""""""""""" |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 604 | |
| 605 | This part is intended for system administrators or downstream OS packagers. |
| 606 | |
| 607 | The real paths of categories are registered in the *sysconfig.cfg* file |
| 608 | installed in your python installation. This file uses an ini format too. |
| 609 | The content of the file is organized into several sections: |
| 610 | |
| 611 | * globals: Standard categories's paths. |
| 612 | * posix_prefix: Standard paths for categories and installation paths for posix |
| 613 | system. |
| 614 | * other ones XXX |
| 615 | |
| 616 | Standard categories paths are platform independent, they generally refers to |
| 617 | other categories, which are platform dependent. :mod:`sysconfig` will choose |
| 618 | these category from sections matching os.name. For example:: |
| 619 | |
| 620 | doc = {datadir}/doc/{distribution.name} |
| 621 | |
| 622 | It refers to datadir category, which can be different between platforms. In |
| 623 | posix system, it may be:: |
| 624 | |
| 625 | datadir = /usr/share |
| 626 | |
| 627 | So the final path will be:: |
| 628 | |
| 629 | doc = /usr/share/doc/{distribution.name} |
| 630 | |
| 631 | The platform-dependent categories are: |
| 632 | |
| 633 | * confdir |
| 634 | * datadir |
| 635 | * libdir |
| 636 | * base |
| 637 | |
| 638 | |
| 639 | Defining extra categories |
Éric Araujo | a462a80 | 2011-06-09 08:15:47 +0200 | [diff] [blame] | 640 | """"""""""""""""""""""""" |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 641 | |
| 642 | .. TODO |
| 643 | |
| 644 | |
| 645 | Examples |
Éric Araujo | a462a80 | 2011-06-09 08:15:47 +0200 | [diff] [blame] | 646 | """""""" |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 647 | |
| 648 | These examples are incremental but work unitarily. |
| 649 | |
| 650 | Resources in root dir |
Éric Araujo | a462a80 | 2011-06-09 08:15:47 +0200 | [diff] [blame] | 651 | ''''''''''''''''''''' |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 652 | |
| 653 | Source tree:: |
| 654 | |
| 655 | babar-1.0/ |
| 656 | README |
| 657 | babar.sh |
| 658 | launch.sh |
| 659 | babar.py |
| 660 | |
| 661 | :file:`setup.cfg`:: |
| 662 | |
| 663 | [files] |
| 664 | resources = |
| 665 | README = {doc} |
| 666 | *.sh = {scripts} |
| 667 | |
| 668 | So babar.sh and launch.sh will be placed in {scripts} directory. |
| 669 | |
| 670 | Now let's move all the scripts into a scripts directory. |
| 671 | |
| 672 | Resources in sub-directory |
Éric Araujo | a462a80 | 2011-06-09 08:15:47 +0200 | [diff] [blame] | 673 | '''''''''''''''''''''''''' |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 674 | |
| 675 | Source tree:: |
| 676 | |
| 677 | babar-1.1/ |
| 678 | README |
| 679 | scripts/ |
| 680 | babar.sh |
| 681 | launch.sh |
| 682 | LAUNCH |
| 683 | babar.py |
| 684 | |
| 685 | :file:`setup.cfg`:: |
| 686 | |
| 687 | [files] |
| 688 | resources = |
| 689 | README = {doc} |
| 690 | scripts/ LAUNCH = {doc} |
| 691 | scripts/ *.sh = {scripts} |
| 692 | |
| 693 | It's important to use the separator after scripts/ to install all the shell |
| 694 | scripts into {scripts} instead of {scripts}/scripts. |
| 695 | |
| 696 | Now let's add some docs. |
| 697 | |
| 698 | Resources in multiple sub-directories |
Éric Araujo | a462a80 | 2011-06-09 08:15:47 +0200 | [diff] [blame] | 699 | ''''''''''''''''''''''''''''''''''''' |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 700 | |
| 701 | Source tree:: |
| 702 | |
| 703 | babar-1.2/ |
| 704 | README |
| 705 | scripts/ |
| 706 | babar.sh |
| 707 | launch.sh |
| 708 | LAUNCH |
| 709 | docs/ |
| 710 | api |
| 711 | man |
| 712 | babar.py |
| 713 | |
| 714 | :file:`setup.cfg`:: |
| 715 | |
| 716 | [files] |
| 717 | resources = |
| 718 | README = {doc} |
| 719 | scripts/ LAUNCH = {doc} |
| 720 | scripts/ *.sh = {scripts} |
| 721 | doc/ * = {doc} |
| 722 | doc/ man = {man} |
| 723 | |
| 724 | You want to place all the file in the docs script into {doc} category, instead |
| 725 | of man, which must be placed into {man} category, we will use the order of |
| 726 | declaration of globs to choose the destination, the last glob that match the |
| 727 | file is used. |
| 728 | |
| 729 | Now let's add some scripts for windows users. |
| 730 | |
| 731 | Complete example |
Éric Araujo | a462a80 | 2011-06-09 08:15:47 +0200 | [diff] [blame] | 732 | '''''''''''''''' |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 733 | |
| 734 | Source tree:: |
| 735 | |
| 736 | babar-1.3/ |
| 737 | README |
| 738 | doc/ |
| 739 | api |
| 740 | man |
| 741 | scripts/ |
| 742 | babar.sh |
| 743 | launch.sh |
| 744 | babar.bat |
| 745 | launch.bat |
| 746 | LAUNCH |
| 747 | |
| 748 | :file:`setup.cfg`:: |
| 749 | |
| 750 | [files] |
| 751 | resources = |
| 752 | README = {doc} |
| 753 | scripts/ LAUNCH = {doc} |
| 754 | scripts/ *.{sh,bat} = {scripts} |
| 755 | doc/ * = {doc} |
| 756 | doc/ man = {man} |
| 757 | |
| 758 | We use brace expansion syntax to place all the shell and batch scripts into |
| 759 | {scripts} category. |
| 760 | |
| 761 | |
Éric Araujo | 79d9c42 | 2011-10-19 08:41:07 +0200 | [diff] [blame] | 762 | .. _setupcfg-section-extensions: |
| 763 | |
| 764 | Extension modules sections |
| 765 | -------------------------- |
Éric Araujo | c7f9f2b | 2011-06-09 08:18:17 +0200 | [diff] [blame] | 766 | |
| 767 | If a project includes extension modules written in C or C++, each one of them |
| 768 | needs to have its options defined in a dedicated section. Here's an example:: |
| 769 | |
| 770 | [files] |
| 771 | packages = coconut |
| 772 | |
Éric Araujo | 336b4e4 | 2011-09-01 06:29:11 +0200 | [diff] [blame] | 773 | [extension: coconut._fastcoconut] |
Éric Araujo | c7f9f2b | 2011-06-09 08:18:17 +0200 | [diff] [blame] | 774 | language = cxx |
| 775 | sources = cxx_src/cononut_utils.cxx |
| 776 | cxx_src/python_module.cxx |
| 777 | include_dirs = /usr/include/gecode |
| 778 | /usr/include/blitz |
| 779 | extra_compile_args = |
| 780 | -fPIC -O2 |
| 781 | -DGECODE_VERSION=$(./gecode_version) -- sys.platform != 'win32' |
Éric Araujo | 0efc419 | 2011-11-14 18:21:38 +0100 | [diff] [blame] | 782 | /DGECODE_VERSION=win32 -- sys.platform == 'win32' |
Éric Araujo | c7f9f2b | 2011-06-09 08:18:17 +0200 | [diff] [blame] | 783 | |
Éric Araujo | 336b4e4 | 2011-09-01 06:29:11 +0200 | [diff] [blame] | 784 | The section name must start with ``extension:``; the right-hand part is used as |
| 785 | the full name (including a parent package, if any) of the extension. Whitespace |
Éric Araujo | d9299e9 | 2011-09-01 07:01:13 +0200 | [diff] [blame] | 786 | around the extension name is allowed. If the extension module is not standalone |
| 787 | (e.g. ``_bisect``) but part of a package (e.g. ``thing._speedups``), the parent |
| 788 | package must be listed in the ``packages`` field. |
Éric Araujo | 336b4e4 | 2011-09-01 06:29:11 +0200 | [diff] [blame] | 789 | Valid fields and their values are listed in the documentation of the |
Éric Araujo | c7f9f2b | 2011-06-09 08:18:17 +0200 | [diff] [blame] | 790 | :class:`packaging.compiler.extension.Extension` class; values documented as |
| 791 | Python lists translate to multi-line values in the configuration file. In |
| 792 | addition, multi-line values accept environment markers on each line, after a |
| 793 | ``--``. |
| 794 | |
| 795 | |
Éric Araujo | 79d9c42 | 2011-10-19 08:41:07 +0200 | [diff] [blame] | 796 | .. _setupcfg-section-commands: |
| 797 | |
| 798 | Commands sections |
| 799 | ----------------- |
Éric Araujo | 3a9f58f | 2011-06-01 20:42:49 +0200 | [diff] [blame] | 800 | |
| 801 | To pass options to commands without having to type them on the command line |
| 802 | for each invocation, you can write them in the :file:`setup.cfg` file, in a |
| 803 | section named after the command. Example:: |
| 804 | |
| 805 | [sdist] |
| 806 | # special function to add custom files |
| 807 | manifest-builders = package.setup.list_extra_files |
| 808 | |
| 809 | [build] |
| 810 | use-2to3 = True |
| 811 | |
| 812 | [build_ext] |
| 813 | inplace = on |
| 814 | |
| 815 | [check] |
| 816 | strict = on |
| 817 | all = on |
| 818 | |
| 819 | Option values given in the configuration file can be overriden on the command |
| 820 | line. See :ref:`packaging-setup-config` for more information. |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 821 | |
Éric Araujo | 79d9c42 | 2011-10-19 08:41:07 +0200 | [diff] [blame] | 822 | These sections are also used to define :ref:`command hooks |
| 823 | <packaging-command-hooks>`. |
| 824 | |
| 825 | |
| 826 | .. _setupcfg-extensibility: |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 827 | |
| 828 | Extensibility |
| 829 | ============= |
| 830 | |
Éric Araujo | 1cf8a32 | 2011-06-06 02:00:03 +0200 | [diff] [blame] | 831 | Every section can have fields that are not part of this specification. They are |
| 832 | called **extensions**. |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 833 | |
Éric Araujo | 1cf8a32 | 2011-06-06 02:00:03 +0200 | [diff] [blame] | 834 | An extension field starts with ``X-``. Example:: |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 835 | |
| 836 | [metadata] |
Éric Araujo | 1cf8a32 | 2011-06-06 02:00:03 +0200 | [diff] [blame] | 837 | name = Distribute |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 838 | X-Debian-Name = python-distribute |
| 839 | |
| 840 | |
Éric Araujo | 79d9c42 | 2011-10-19 08:41:07 +0200 | [diff] [blame] | 841 | .. _setupcfg-changes: |
| 842 | |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 843 | Changes in the specification |
| 844 | ============================ |
| 845 | |
Éric Araujo | a69ade8 | 2011-06-06 02:02:34 +0200 | [diff] [blame] | 846 | The versioning scheme for this specification is **MAJOR.MINOR**. Changes in the |
| 847 | specification will cause the version number to be updated. |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 848 | |
Éric Araujo | a69ade8 | 2011-06-06 02:02:34 +0200 | [diff] [blame] | 849 | Changes to the minor number reflect backwards-compatible changes: |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 850 | |
Éric Araujo | a69ade8 | 2011-06-06 02:02:34 +0200 | [diff] [blame] | 851 | - New fields and sections (optional or mandatory) can be added. |
| 852 | - Optional fields can be removed. |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 853 | |
Éric Araujo | a69ade8 | 2011-06-06 02:02:34 +0200 | [diff] [blame] | 854 | The major number will be incremented for backwards-incompatible changes: |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 855 | |
Éric Araujo | a69ade8 | 2011-06-06 02:02:34 +0200 | [diff] [blame] | 856 | - Mandatory fields or sections are removed. |
| 857 | - Fields change their meaning. |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 858 | |
Éric Araujo | a69ade8 | 2011-06-06 02:02:34 +0200 | [diff] [blame] | 859 | As a consequence, a tool written to consume 1.5 has these properties: |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 860 | |
Éric Araujo | a69ade8 | 2011-06-06 02:02:34 +0200 | [diff] [blame] | 861 | - Can read 1.1, 1.2 and all versions < 1.5, since the tool knows what |
| 862 | optional fields weren't there. |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 863 | |
Éric Araujo | a69ade8 | 2011-06-06 02:02:34 +0200 | [diff] [blame] | 864 | .. XXX clarify |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 865 | |
Éric Araujo | a69ade8 | 2011-06-06 02:02:34 +0200 | [diff] [blame] | 866 | - Can also read 1.6 and other 1.x versions: The tool will just ignore fields it |
| 867 | doesn't know about, even if they are mandatory in the new version. If |
| 868 | optional fields were removed, the tool will just consider them absent. |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 869 | |
Éric Araujo | a69ade8 | 2011-06-06 02:02:34 +0200 | [diff] [blame] | 870 | - Cannot read 2.x and should refuse to interpret such files. |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 871 | |
Éric Araujo | a69ade8 | 2011-06-06 02:02:34 +0200 | [diff] [blame] | 872 | A tool written to produce 1.x should have these properties: |
Éric Araujo | ba661a9 | 2011-06-04 02:31:14 +0200 | [diff] [blame] | 873 | |
Éric Araujo | a69ade8 | 2011-06-06 02:02:34 +0200 | [diff] [blame] | 874 | - Writes all mandatory fields. |
| 875 | - May write optional fields. |
Éric Araujo | 1cf8a32 | 2011-06-06 02:00:03 +0200 | [diff] [blame] | 876 | |
| 877 | |
Éric Araujo | 79d9c42 | 2011-10-19 08:41:07 +0200 | [diff] [blame] | 878 | .. _setupcfg-acks: |
| 879 | |
Éric Araujo | 1cf8a32 | 2011-06-06 02:00:03 +0200 | [diff] [blame] | 880 | Acknowledgments |
| 881 | =============== |
| 882 | |
| 883 | This specification includes work and feedback from these people: |
| 884 | |
| 885 | - Tarek Ziadé |
| 886 | - Julien Jehannet |
| 887 | - Boris Feld |
| 888 | - Éric Araujo |
| 889 | |
| 890 | (If your name is missing, please :ref:`let us know <reporting-bugs>`.) |