Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unwrap method to recursive convert to plain old python objects #187

Merged
merged 22 commits into from May 22, 2022
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
81 changes: 81 additions & 0 deletions tests/test_items.py
Expand Up @@ -8,21 +8,33 @@

import pytest

from .util import assert_is_ppo
from .util import elementary_test

from tomlkit import api
from tomlkit import parse
from tomlkit.exceptions import NonExistentKey
from tomlkit.items import Bool
from tomlkit.items import Comment
from tomlkit.items import InlineTable
from tomlkit.items import Integer
from tomlkit.items import Float
from tomlkit.items import DateTime
from tomlkit.items import Date
from tomlkit.items import Time
from tomlkit.items import Array
from tomlkit.items import KeyType
from tomlkit.items import SingleKey as Key
from tomlkit.items import String
from tomlkit.items import StringType
from tomlkit.items import Table
from tomlkit.items import Trivia
from tomlkit.items import Item
from tomlkit.items import AoT
from tomlkit.items import item
from tomlkit.items import Null
from tomlkit.parser import Parser
from tomlkit.check import is_tomlkit


@pytest.fixture()
Expand Down Expand Up @@ -69,6 +81,75 @@ def dst(self, dt):
return UTC()


def test_item_base_has_no_unwrap():
trivia = Trivia(indent='\t', comment_ws=' ', comment='For unit test')
item = Item(trivia)
try:
item.unwrap()
except NotImplementedError:
pass
else:
raise AssertionError("`items.Item` should not implement `unwrap`")

def test_integer_unwrap():
elementary_test(item(666), int)
def test_float_unwrap():
elementary_test(item(2.78), float)
def test_false_unwrap():
elementary_test(item(False), bool)
def test_true_unwrap():
elementary_test(item(True), bool)
def test_datetime_unwrap():
dt=datetime.utcnow()
elementary_test(item(dt), datetime)
def test_string_unwrap():
elementary_test(item("hello"), str)
def test_null_unwrap():
n = Null()
elementary_test(n, type(None))
def test_aot_unwrap():
d = item([{"a": "A"}, {"b": "B"}])
assert is_tomlkit(d)
unwrapped = d.unwrap()
assert_is_ppo(unwrapped, list)
for du, dw in zip(unwrapped, d):
assert_is_ppo(du, dict)
for ku in du:
vu = du[ku]
assert_is_ppo(ku, str)
assert_is_ppo(vu, str)

def test_time_unwrap():
t=time(3, 8, 14)
elementary_test(item(t), time)
def test_date_unwrap():
d=date.today()
elementary_test(item(d), date)
def test_array_unwrap():
trivia = Trivia(indent='\t', comment_ws=' ', comment='For unit test')
i=item(666)
f=item(2.78)
b=item(False)
a=Array([i, f, b], trivia)
a_unwrapped=a.unwrap()
assert_is_ppo(a_unwrapped, list)
assert_is_ppo(a_unwrapped[0], int)
assert_is_ppo(a_unwrapped[1], float)
assert_is_ppo(a_unwrapped[2], bool)
def test_abstract_table_unwrap():
table = item({"foo": "bar"})
super_table = item({"table": table, "baz": "borg"})
assert is_tomlkit(super_table["table"])

table_unwrapped = super_table.unwrap()
sub_table = table_unwrapped["table"]
assert_is_ppo(table_unwrapped, dict)
assert_is_ppo(sub_table, dict)
for ku in sub_table:
vu = sub_table[ku]
assert_is_ppo(ku, str)
assert_is_ppo(vu, str)

def test_key_comparison():
k = Key("foo")

Expand Down
17 changes: 17 additions & 0 deletions tests/test_toml_document.py
Expand Up @@ -9,11 +9,15 @@

import tomlkit

from .util import assert_is_ppo
from .util import elementary_test

from tomlkit import parse
from tomlkit import ws
from tomlkit._utils import _utc
from tomlkit.api import document
from tomlkit.exceptions import NonExistentKey
from tomlkit.toml_document import TOMLDocument


def test_document_is_a_dict(example):
Expand Down Expand Up @@ -153,6 +157,19 @@ def test_toml_document_without_super_tables():

assert "tool" in d

def test_toml_document_unwrap():
content = """[tool.poetry]
name = "foo"
"""

doc = parse(content)
unwrapped=doc.unwrap()
assert_is_ppo(unwrapped, dict)
assert_is_ppo(list(unwrapped.keys())[0], str)
assert_is_ppo(unwrapped["tool"], dict)
assert_is_ppo(list(unwrapped["tool"].keys())[0], str)
assert_is_ppo(unwrapped["tool"]["poetry"]["name"], str)


def test_toml_document_with_dotted_keys(example):
content = example("0.5.0")
Expand Down
53 changes: 53 additions & 0 deletions tests/util.py
@@ -0,0 +1,53 @@
from tomlkit.items import Bool
from tomlkit.items import Comment
from tomlkit.items import InlineTable
from tomlkit.items import Integer
from tomlkit.items import Float
from tomlkit.items import DateTime
from tomlkit.items import Date
from tomlkit.items import Time
from tomlkit.items import Array
from tomlkit.items import KeyType
from tomlkit.items import SingleKey as Key
from tomlkit.items import String
from tomlkit.items import StringType
from tomlkit.items import Table
from tomlkit.items import Trivia
from tomlkit.items import Item
from tomlkit.items import AoT
from tomlkit.items import Null
from tomlkit.toml_document import TOMLDocument

TOMLKIT_TYPES = [
Bool,
Comment,
InlineTable,
Integer,
Float,
DateTime,
Date,
Time,
Array,
KeyType,
Key,
String,
StringType,
Table,
Trivia,
Item,
AoT,
Null,
TOMLDocument
]

def assert_not_tomlkit_type(v):
for i, T in enumerate(TOMLKIT_TYPES):
assert not isinstance(v, T)

def assert_is_ppo(v_unwrapped, unwrappedType):
assert_not_tomlkit_type(v_unwrapped)
assert isinstance(v_unwrapped, unwrappedType)

def elementary_test(v, unwrappedType):
v_unwrapped = v.unwrap()
assert_is_ppo(v_unwrapped, unwrappedType)
11 changes: 11 additions & 0 deletions tomlkit/check.py
@@ -0,0 +1,11 @@
def is_tomlkit(v):
from .items import Item as _Item
from .container import Container
from .container import OutOfOrderTableProxy
if isinstance(v, _Item):
return True
if isinstance(v, Container):
return True
if isinstance(v, OutOfOrderTableProxy):
return True
return False
24 changes: 24 additions & 0 deletions tomlkit/container.py
Expand Up @@ -25,6 +25,8 @@
from .items import _CustomDict
from .items import item as _item

from .check import is_tomlkit


_NOT_SET = object()

Expand All @@ -46,6 +48,25 @@ def __init__(self, parsed: bool = False) -> None:
def body(self) -> List[Tuple[Optional[Key], Item]]:
return self._body

def unwrap(self) -> str:
unwrapped = {}
for k, v in self.items():
if k is None:
continue

if not isinstance(k, str):
k = k.key

if isinstance(v, Item):
v = v.unwrap()

if k in unwrapped:
merge_dicts(unwrapped[k], v)
else:
unwrapped[k] = v

return unwrapped

@property
def value(self) -> Dict[Any, Any]:
d = {}
Expand Down Expand Up @@ -796,6 +817,9 @@ def __init__(self, container: Container, indices: Tuple[int]) -> None:
if k is not None:
dict.__setitem__(self, k.key, v)

def unwrap(self) -> str:
return self._internal_container.unwrap()

@property
def value(self):
return self._internal_container.value
Expand Down