Metadata-Version: 2.4
Name: tox-toml-fmt
Version: 1.5.0
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Dist: toml-fmt-common==1.2
License-File: LICENSE.txt
Summary: Format your pyproject.toml file
Keywords: format,pyproject
Author-email: Bernat Gabor <gaborjbernat@gmail.com>
Requires-Python: >=3.10
Description-Content-Type: text/x-rst
Project-URL: Bug Tracker, https://github.com/tox-dev/toml-fmt/issues
Project-URL: Changelog, https://github.com/tox-dev/toml-fmt/blob/main/tox-toml-fmt/CHANGELOG.md
Project-URL: Documentation, https://tox-toml-fmt.readthedocs.io/en/latest/
Project-URL: Source Code, https://github.com/tox-dev/toml-fmt/tree/main/tox-toml-fmt

Overview
========

Apply a consistent format to your ``tox.toml`` file with comment support. See
`changelog here <https://github.com/tox-dev/toml-fmt/blob/main/tox-toml-fmt/CHANGELOG.md>`_.


Recent Changes
~~~~~~~~~~~~~~~~

- ✨ feat(changelog): add --regenerate flag for full changelog rebuild by `@gaborbernat <https://github.com/gaborbernat>`_
  in `#166 <https://github.com/tox-dev/toml-fmt/pull/166>`_
- 🐛 fix(readme): use explicit UTF-8 encoding for file operations by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#165 <https://github.com/tox-dev/toml-fmt/pull/165>`_
- Release tox-toml-fmt 1.4.0 by `@gaborbernat <https://github.com/gaborbernat>`_
- 📝 docs(formatting): restructure docs and fix array formatting behavior by
  `@gaborbernat <https://github.com/gaborbernat>`_ in `#164 <https://github.com/tox-dev/toml-fmt/pull/164>`_
- ♻️ refactor(parser): migrate from taplo to tombi by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#159 <https://github.com/tox-dev/toml-fmt/pull/159>`_
- Fix expand_tables setting for deeply nested tables (#146) by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#160 <https://github.com/tox-dev/toml-fmt/pull/160>`_
- Prefer double quotes, use single quotes to avoid escaping by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#162 <https://github.com/tox-dev/toml-fmt/pull/162>`_
- Fix comment before table moving incorrectly when table has comments by `@gaborbernat <https://github.com/gaborbernat>`_
  in `#158 <https://github.com/tox-dev/toml-fmt/pull/158>`_
- Add tests to improve coverage for edge cases by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#155 <https://github.com/tox-dev/toml-fmt/pull/155>`_
- Fix expand_tables setting for specific sub-tables by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#148 <https://github.com/tox-dev/toml-fmt/pull/148>`_
- Use RELEASE_TOKEN to bypass branch protection for releases by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#147 <https://github.com/tox-dev/toml-fmt/pull/147>`_
- Generate README.rst dynamically from docs at build time by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#145 <https://github.com/tox-dev/toml-fmt/pull/145>`_
- 📚 Document formatting principles and normalizations by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#144 <https://github.com/tox-dev/toml-fmt/pull/144>`_
- Improve maintainalibility by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#143 <https://github.com/tox-dev/toml-fmt/pull/143>`_
- Add configurable table formatting to pyproject-fmt and order tox env tables by env_list by
  `@gaborbernat <https://github.com/gaborbernat>`_ in `#142 <https://github.com/tox-dev/toml-fmt/pull/142>`_
- Order tox env tables according to env_list and add codecov token by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#141 <https://github.com/tox-dev/toml-fmt/pull/141>`_
- Fix comments before table headers staying with correct table by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#140 <https://github.com/tox-dev/toml-fmt/pull/140>`_
- Sort subtables alphabetically within the same tool by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#139 <https://github.com/tox-dev/toml-fmt/pull/139>`_
- Collapse [[project.authors]] array of tables to inline format by [@gaborbernat](https://github.com/gaborbernat) in
  `#137 <https://github.com/tox-dev/toml-fmt/pull/137>`_
- Bump toml-fmt-common to 1.2 by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#138 <https://github.com/tox-dev/toml-fmt/pull/138>`_
- Add keyword and classifier deduplication by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#133 <https://github.com/tox-dev/toml-fmt/pull/133>`_
- Fix crash on multi-line strings with line continuation by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#132 <https://github.com/tox-dev/toml-fmt/pull/132>`_
- Add PEP 794 private dependency support by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#131 <https://github.com/tox-dev/toml-fmt/pull/131>`_
- Fix literal strings with invalid escapes being corrupted by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#130 <https://github.com/tox-dev/toml-fmt/pull/130>`_
- Remove testpaths config to fix sdist warning (#120) by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#129 <https://github.com/tox-dev/toml-fmt/pull/129>`_
- Fix build requirements with duplicate package names being removed (#2) by
  `@gaborbernat <https://github.com/gaborbernat>`_ in `#127 <https://github.com/tox-dev/toml-fmt/pull/127>`_
- Improve CI: add Rust coverage thresholds and prek parallel hooks by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#126 <https://github.com/tox-dev/toml-fmt/pull/126>`_
- Improve GitHub Actions workflows by `@gaborbernat <https://github.com/gaborbernat>`_ in
  `#125 <https://github.com/tox-dev/toml-fmt/pull/125>`_ <a id="1.3.0"></a>

Philosophy
----------
This tool aims to be an *opinionated formatter*, with similar objectives to `black <https://github.com/psf/black>`_.
This means it deliberately does not support a wide variety of configuration settings. In return, you get consistency,
predictability, and smaller diffs.

Use
---

Via ``CLI``
~~~~~~~~~~~

`tox-toml-fmt <https://pypi.org/project/tox-toml-fmt>`_ is a CLI tool that needs a Python interpreter (version 3.10 or higher) to run. We recommend
either `pipx <https://pypi.org/project/pipx>`_ or `uv <https://pypi.org/project/uv>`_ to install tox-toml-fmt into an isolated environment. This has the added benefit that
later you will be able to upgrade tox-toml-fmt without affecting other parts of the system. We provide a method for
``pip`` too here, but we discourage that path if you can:


    .. code-block:: bash

        # install uv per https://docs.astral.sh/uv/#getting-started
        uv tool install tox-toml-fmt
        tox-toml-fmt --help


Via ``pre-commit`` hook
~~~~~~~~~~~~~~~~~~~~~~~

See `pre-commit/pre-commit <https://github.com/pre-commit/pre-commit>`_ for instructions, sample ``.pre-commit-config.yaml``:

.. code-block:: yaml

    - repo: https://github.com/tox-dev/tox-toml-fmt
      rev: "v1.0.0"
      hooks:
        - id: tox-toml-fmt

Via Python
~~~~~~~~~~

You can use ``tox-toml-fmt`` as a Python module to format TOML content programmatically.

.. code-block:: python

    from tox_toml_fmt import run

    # Format a tox.toml file and return the exit code
    exit_code = run(["path/to/tox.toml"])

The ``run`` function accepts command-line arguments as a list and returns an exit code (0 for success, non-zero for
failure).


The ``[tox-toml-fmt]`` table is used when present in the ``tox.toml`` file:

.. code-block:: toml

    [tox-toml-fmt]

    # After how many columns split arrays/dicts into multiple lines (1 forces always)
    column_width = 120

    # Number of spaces for indentation
    indent = 2

If not set they will default to values from the CLI. The example above shows the defaults.

``tox-toml-fmt`` is an opinionated formatter, much like `black <https://github.com/psf/black>`_ is for Python code.
The tool intentionally provides minimal configuration options because the goal is to establish a single standard format
that all ``tox.toml`` files follow.

**Benefits of this approach:**

- Less time configuring tools
- Smaller diffs when committing changes
- Easier code reviews since formatting is never a question

While a few key options exist (``column_width``, ``indent``), the tool does not expose dozens of toggles. You get what
the maintainers have chosen to be the right balance of readability, consistency, and usability.

General Formatting
------------------

These rules apply uniformly across the entire ``tox.toml`` file.

String Quotes
~~~~~~~~~~~~~

All strings use double quotes by default. Single quotes are only used when the value contains double quotes:

.. code-block:: toml

    # Before
    description = 'Run tests'
    commands = ["echo \"hello\""]

    # After
    description = "Run tests"
    commands = ['echo "hello"']

Array Formatting
~~~~~~~~~~~~~~~~

Arrays are formatted based on line length, trailing comma presence, and comments:

.. code-block:: toml

    # Short arrays stay on one line
    env_list = ["py312", "py313", "lint"]

    # Long arrays that exceed column_width are expanded and get a trailing comma
    deps = [
        "pytest>=7",
        "pytest-cov>=4",
        "pytest-mock>=3",
    ]

    # Trailing commas signal intent to keep multiline format
    deps = [
        "pytest>=7",
    ]

    # Arrays with comments are always multiline
    deps = [
        "pytest>=7",  # testing framework
        "coverage>=7",
    ]

**Multiline formatting rules:**

An array becomes multiline when any of these conditions are met:

1. **Trailing comma present** - A trailing comma signals intent to keep multiline format
2. **Exceeds column width** - Arrays longer than ``column_width`` are expanded (and get a trailing comma added)
3. **Contains comments** - Arrays with inline or leading comments are always multiline

Comment Preservation
~~~~~~~~~~~~~~~~~~~~

All comments are preserved during formatting:

- **Inline comments** - Comments after a value on the same line stay with that value
- **Leading comments** - Comments on the line before an entry stay with the entry below
- **Block comments** - Multi-line comment blocks are preserved

**Inline comment alignment:**

Inline comments within arrays are aligned independently per array, based on that array's longest value:

.. code-block:: toml

    # Before - comments at inconsistent positions
    deps = [
      "pytest", # testing
      "pytest-cov",  # coverage
      "pytest-mock", # mocking
    ]

    # After - comments align to longest value in this array
    deps = [
      "pytest",       # testing
      "pytest-cov",   # coverage
      "pytest-mock",  # mocking
    ]

Table-Specific Handling
-----------------------

Table Ordering
~~~~~~~~~~~~~~

Tables are reordered into a consistent structure:

1. Root-level keys (``env_list``, ``min_version``, ``skip_missing_interpreters``)
2. ``[env_run_base]``
3. ``[env.NAME]`` sections ordered by ``env_list`` if specified
4. Any remaining ``[env.*]`` sections not in ``env_list``

.. code-block:: toml

    # env_list determines the order of [env.*] sections
    env_list = ["lint", "type", "py312", "py313"]

    [env_run_base]
    deps = ["pytest>=7"]

    # Environments appear in env_list order:
    [env.lint]
    # ...

    [env.type]
    # ...

    [env.py312]
    # ...

    [env.py313]
    # ...

Environments not listed in ``env_list`` are placed at the end.

Other Tables
~~~~~~~~~~~~

Any unrecognized tables are preserved and reordered according to standard table ordering rules. Keys within tables
are not reordered.
