Skip to content

Commit

Permalink
Support Decimal and MutableMapping encoding
Browse files Browse the repository at this point in the history
For `decimal.Decimal` we can just encode as a `String` and leave it up
to the user how to decode the value on load. For `dict` it's quite handy
to just render any type that quacks like a `MutableMapping` to a table.

Resolves python-poetry#288 and python-poetry#289 but still needs tests!
  • Loading branch information
goodboy committed May 25, 2023
1 parent 3fa5446 commit df93c33
Showing 1 changed file with 22 additions and 5 deletions.
27 changes: 22 additions & 5 deletions tomlkit/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import re
import string

from collections.abc import MutableMapping
from datetime import date
from datetime import datetime
from datetime import time
from datetime import tzinfo
from decimal import Decimal
from enum import Enum
from typing import TYPE_CHECKING
from typing import Any
Expand Down Expand Up @@ -74,6 +76,13 @@ def item(
...


@overload
def item(
value: Decimal, _parent: Optional["Item"] = ..., _sort_keys: bool = ...
) -> "String":
...


@overload
def item(
value: float, _parent: Optional["Item"] = ..., _sort_keys: bool = ...
Expand Down Expand Up @@ -167,24 +176,29 @@ def item(
return Bool(value, Trivia())
elif isinstance(value, int):
return Integer(value, Trivia(), str(value))
elif isinstance(value, Decimal):
return String.from_raw(str(value))
elif isinstance(value, float):
return Float(value, Trivia(), str(value))
elif isinstance(value, dict):
elif isinstance(value, MutableMapping):
table_constructor = (
InlineTable if isinstance(_parent, (Array, InlineTable)) else Table
)
val = table_constructor(Container(), Trivia(), False)
for k, v in sorted(
value.items(),
key=lambda i: (isinstance(i[1], dict), i[0] if _sort_keys else 1),
key=lambda i: (
isinstance(i[1], MutableMapping),
i[0] if _sort_keys else 1
),
):
val[k] = item(v, _parent=val, _sort_keys=_sort_keys)

return val
elif isinstance(value, (list, tuple)):
if (
value
and all(isinstance(v, dict) for v in value)
and all(isinstance(v, MutableMapping) for v in value)
and (_parent is None or isinstance(_parent, Table))
):
a = AoT([])
Expand All @@ -194,12 +208,15 @@ def item(
table_constructor = InlineTable

for v in value:
if isinstance(v, dict):
if isinstance(v, MutableMapping):
table = table_constructor(Container(), Trivia(), True)

for k, _v in sorted(
v.items(),
key=lambda i: (isinstance(i[1], dict), i[0] if _sort_keys else 1),
key=lambda i: (
isinstance(i[1], MutableMapping),
i[0] if _sort_keys else 1
),
):
i = item(_v, _parent=table, _sort_keys=_sort_keys)
if isinstance(table, InlineTable):
Expand Down

0 comments on commit df93c33

Please sign in to comment.