Skip to content

Commit

Permalink
Fix bug involving weird sort order of nested tables
Browse files Browse the repository at this point in the history
Also, tidies up the containers special case, handling in one place
and simplifying the type interface to only be Item
  • Loading branch information
pappasam committed Aug 14, 2019
1 parent 77a8f57 commit 96243ba
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 28 deletions.
24 changes: 12 additions & 12 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"

[tool.black]
line-length = 79

[tool.poetry]
name = "toml-sort"
version = "0.14.0"
version = "0.15.0"
description = "Toml sorting library"
authors = ["Sam Roeca <[email protected]>"]
readme = "README.md"
Expand All @@ -29,14 +26,6 @@ python = "^3.6"
tomlkit = ">=0.5.5"
click = "^7.0"

[tool.poetry.dev-dependencies]
pylint = "^2.3"
black = {version = "^19.3b0", allows-prereleases = true}
mypy = "^0.720.0"
pre-commit = "^1.18"
tox = "^3.13"
pytest = "^5.0"

[tool.poetry.scripts]
toml-sort = 'toml_sort.cli:cli'

Expand All @@ -57,3 +46,14 @@ commands =
poetry run pylint toml_sort tests
poetry run pytest
"""

[tool.black]
line-length = 79

[tool.poetry.dev-dependencies]
pylint = "^2.3"
black = {version = "^19.3b0", allows-prereleases = true}
mypy = "^0.720.0"
pre-commit = "^1.18"
tox = "^3.13"
pytest = "^5.0"
24 changes: 24 additions & 0 deletions tests/examples/defaults/pyproject-weird-order.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[build-system]
requires = ["poetry>=0.12"]

[tool.black]
line-length = 79

[tool.poetry]
name = "toml-sort"
version = "0.14.0"

[tool.poetry.dependencies]
python = "^3.6"

[tool.poetry.dev-dependencies]
pylint = "^2.3"

[tool.poetry.scripts]
toml-sort = 'toml_sort.cli:cli'

[tool.tox]
legacy_tox_ini = """
[tox]
envlist = py36,py37
"""
24 changes: 24 additions & 0 deletions tests/examples/pyproject-weird-order.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[build-system]
requires = ["poetry>=0.12"]

[tool.poetry]
name = "toml-sort"
version = "0.14.0"

[tool.poetry.dependencies]
python = "^3.6"

[tool.poetry.scripts]
toml-sort = 'toml_sort.cli:cli'

[tool.tox]
legacy_tox_ini = """
[tox]
envlist = py36,py37
"""

[tool.black]
line-length = 79

[tool.poetry.dev-dependencies]
pylint = "^2.3"
1 change: 1 addition & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
[
("from-toml-lang.toml", "defaults/from-toml-lang.toml"),
("weird.toml", "defaults/weird.toml"),
("pyproject-weird-order.toml", "defaults/pyproject-weird-order.toml"),
],
)
def test_cli_defaults(path_unsorted: str, path_sorted: str) -> None:
Expand Down
43 changes: 27 additions & 16 deletions toml_sort/tomlsort.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@

import re
import itertools
from typing import Iterable, Tuple, Set, Union
from typing import Iterable, Tuple, Set

import tomlkit
from tomlkit.api import aot, ws, item, table
from tomlkit.api import aot, ws, item
from tomlkit.toml_document import TOMLDocument
from tomlkit.container import Container
from tomlkit.items import Item, Table, AoT, Comment, Whitespace
from tomlkit.items import Item, Table, AoT, Comment, Whitespace, Trivia


def clean_toml_text(input_toml: str) -> str:
Expand All @@ -38,6 +38,18 @@ def write_header_comment(from_doc: TOMLDocument, to_doc: TOMLDocument) -> None:
return


def convert_tomlkit_buggy_types(in_value: object, parent: Item) -> Item:
"""Fix buggy items while iterating through tomlkit items
Iterating through tomlkit items can often be buggy; this function fixes it
"""
if isinstance(in_value, Item):
return in_value
if isinstance(in_value, Container):
return Table(in_value, trivia=Trivia(), is_aot_element=False)
return item(in_value, parent)


class TomlSort:
"""API to manage sorting toml files"""

Expand All @@ -59,22 +71,26 @@ def __init__(

def sorted_children_table(
self, parent: Table
) -> Iterable[Tuple[str, Union[Item, Container]]]:
) -> Iterable[Tuple[str, Item]]:
"""Get the sorted children of a table
NOTE: non-tables are wrapped in an item to ensure that they are, in
fact, items. Tables and AoT's are definitely items, so the conversion
is not necessary.
"""
table_items = [
(key, convert_tomlkit_buggy_types(parent[key], parent))
for key in parent.keys()
]
tables = (
(key, parent[key])
for key in parent
if isinstance(parent[key], (Table, AoT, Container))
(key, value)
for key, value in table_items
if isinstance(value, (Table, AoT))
)
non_tables = (
(key, item(parent[key], parent))
for key in parent
if not isinstance(parent[key], (Table, AoT))
(key, value)
for key, value in table_items
if not isinstance(value, (Table, AoT))
)
non_tables_final = (
sorted(non_tables, key=lambda x: x[0])
Expand All @@ -87,11 +103,6 @@ def sorted_children_table(

def toml_elements_sorted(self, original: Item) -> Item:
"""Returns a sorted item, recursing collections to their base"""
if isinstance(original, Container):
new_table = table()
for key, value in self.sorted_children_table(original):
new_table[key] = self.toml_elements_sorted(value)
return new_table
if isinstance(original, Table):
original.trivia.indent = "\n"
new_table = Table(
Expand Down Expand Up @@ -122,7 +133,7 @@ def toml_elements_sorted(self, original: Item) -> Item:
original.trivia.indent = ""
return original
raise TypeError(
"Invalid TOML; " + str(type(original)) + " is not an Item"
"Invalid TOML; " + str(type(original)) + " is not an Item."
)

def toml_doc_sorted(self, original: TOMLDocument) -> TOMLDocument:
Expand Down

0 comments on commit 96243ba

Please sign in to comment.