From a840172a0e09aaf7fee95cad740dbca00178d4b5 Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Mon, 11 Apr 2022 21:34:53 -0700 Subject: [PATCH 01/22] add as_ppo method for elementary types --- tomlkit/items.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tomlkit/items.py b/tomlkit/items.py index bdc97f2..966a851 100644 --- a/tomlkit/items.py +++ b/tomlkit/items.py @@ -492,6 +492,10 @@ def as_string(self) -> str: """The TOML representation""" raise NotImplementedError() + def as_ppo(self): + """Returns as pure python object (ppo)""" + raise NotImplementedError() + # Helpers def comment(self, comment: str) -> "Item": @@ -534,6 +538,8 @@ def __reduce__(self): def __reduce_ex__(self, protocol): return self.__class__, self._getstate(protocol) + def + class Whitespace(Item): """ @@ -610,6 +616,9 @@ def __init__(self, _: int, trivia: Trivia, raw: str) -> None: if re.match(r"^[+\-]\d+$", raw): self._sign = True + def as_ppo(self) -> int: + return int(self) + @property def discriminant(self) -> int: return 2 @@ -678,6 +687,9 @@ def __init__(self, _: float, trivia: Trivia, raw: str) -> None: if re.match(r"^[+\-].+$", raw): self._sign = True + def as_ppo(self) -> float: + return float(self) + @property def discriminant(self) -> int: return 3 @@ -739,6 +751,9 @@ def __init__(self, t: int, trivia: Trivia) -> None: self._value = bool(t) + def as_ppo(self) -> bool: + return bool(self) + @property def discriminant(self) -> int: return 4 @@ -821,6 +836,10 @@ def __init__( self._raw = raw or self.isoformat() + def as_ppo(self) -> datetime: + (year, month, day, hour, minute, second, microsecond, tzinfo, _, _) = self._getstate() + return datetime(year, month, day, hour, minute, second, microsecond, tzinfo) + @property def discriminant(self) -> int: return 5 @@ -924,6 +943,10 @@ def __init__( self._raw = raw + def as_ppo(self) -> date: + (year, month, day, _, _) = self._getstate() + return date(year, month, day) + @property def discriminant(self) -> int: return 6 @@ -996,6 +1019,10 @@ def __init__( self._raw = raw + def as_ppo(self) -> datetime: + (hour, minute, second, microsecond, tzinfo, _, _) = self._getstate() + return time(hour, minute, second, microsecond, tzinfo) + @property def discriminant(self) -> int: return 7 @@ -1295,6 +1322,9 @@ def __init__(self, value: "container.Container", trivia: Trivia): if k is not None: dict.__setitem__(self, k.key, v) + def as_ppo(self): + pass + @property def value(self) -> "container.Container": return self._value @@ -1617,6 +1647,9 @@ def __init__(self, t: StringType, _: str, original: str, trivia: Trivia) -> None self._t = t self._original = original + def as_ppo(self) -> str: + return self.as_string() + @property def discriminant(self) -> int: return 11 From 6b027b30afb82a83ecba1f95dbf956e40023824c Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Thu, 14 Apr 2022 13:10:06 -0700 Subject: [PATCH 02/22] rename as_popo to unwrap; add recursive arg --- tomlkit/items.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tomlkit/items.py b/tomlkit/items.py index 966a851..94202b7 100644 --- a/tomlkit/items.py +++ b/tomlkit/items.py @@ -492,7 +492,7 @@ def as_string(self) -> str: """The TOML representation""" raise NotImplementedError() - def as_ppo(self): + def unwrap(self, recursive: bool = True): """Returns as pure python object (ppo)""" raise NotImplementedError() @@ -616,7 +616,7 @@ def __init__(self, _: int, trivia: Trivia, raw: str) -> None: if re.match(r"^[+\-]\d+$", raw): self._sign = True - def as_ppo(self) -> int: + def unwrap(self, recursive: bool = True) -> int: return int(self) @property @@ -687,7 +687,7 @@ def __init__(self, _: float, trivia: Trivia, raw: str) -> None: if re.match(r"^[+\-].+$", raw): self._sign = True - def as_ppo(self) -> float: + def unwrap(self, recursive: bool = True) -> float: return float(self) @property @@ -751,7 +751,7 @@ def __init__(self, t: int, trivia: Trivia) -> None: self._value = bool(t) - def as_ppo(self) -> bool: + def unwrap(self, recursive: bool = True) -> bool: return bool(self) @property @@ -836,7 +836,7 @@ def __init__( self._raw = raw or self.isoformat() - def as_ppo(self) -> datetime: + def unwrap(self, recursive: bool = True) -> datetime: (year, month, day, hour, minute, second, microsecond, tzinfo, _, _) = self._getstate() return datetime(year, month, day, hour, minute, second, microsecond, tzinfo) @@ -943,7 +943,7 @@ def __init__( self._raw = raw - def as_ppo(self) -> date: + def unwrap(self, recursive: bool = True) -> date: (year, month, day, _, _) = self._getstate() return date(year, month, day) @@ -1019,7 +1019,7 @@ def __init__( self._raw = raw - def as_ppo(self) -> datetime: + def unwrap(self, recursive: bool = True) -> datetime: (hour, minute, second, microsecond, tzinfo, _, _) = self._getstate() return time(hour, minute, second, microsecond, tzinfo) @@ -1322,7 +1322,7 @@ def __init__(self, value: "container.Container", trivia: Trivia): if k is not None: dict.__setitem__(self, k.key, v) - def as_ppo(self): + def unwrap(self, recursive: bool = True): pass @property @@ -1647,7 +1647,7 @@ def __init__(self, t: StringType, _: str, original: str, trivia: Trivia) -> None self._t = t self._original = original - def as_ppo(self) -> str: + def unwrap(self, recursive: bool = True) -> str: return self.as_string() @property From adf79bd0310b5db306786f7bf3e830c503d7e40c Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Thu, 14 Apr 2022 13:52:19 -0700 Subject: [PATCH 03/22] add unwrap methods to collection types + Null --- tomlkit/container.py | 22 ++++++++++++++++++++++ tomlkit/items.py | 30 +++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/tomlkit/container.py b/tomlkit/container.py index 2db19e3..c0da383 100644 --- a/tomlkit/container.py +++ b/tomlkit/container.py @@ -46,6 +46,25 @@ def __init__(self, parsed: bool = False) -> None: def body(self) -> List[Tuple[Optional[Key], Item]]: return self._body + def unwrap(self, recursive: bool = True) -> str: + unwrapped = {} + for k, v in self._body: + if k is None: + continue + + k = k.key + v = v.value + + if isinstance(v, Container): + v = v.unwrap(recursive=recursive) + + if k in unwrapped: + merge_dicts(unwrapped[k], v) + else: + unwrapped[k] = v.unwrap(recursive=recursive) + + return unwrapped + @property def value(self) -> Dict[Any, Any]: d = {} @@ -796,6 +815,9 @@ def __init__(self, container: Container, indices: Tuple[int]) -> None: if k is not None: dict.__setitem__(self, k.key, v) + def unwrap(self, recursive: bool = True) -> str: + return self._internal_container.unwrap(recursive=recursive) + @property def value(self): return self._internal_container.value diff --git a/tomlkit/items.py b/tomlkit/items.py index 94202b7..7eab7a8 100644 --- a/tomlkit/items.py +++ b/tomlkit/items.py @@ -1078,6 +1078,15 @@ def __init__(self, value: list, trivia: Trivia, multiline: bool = False) -> None self._multiline = multiline self._reindex() + def unwrap(self, recursive: bool = True) -> str: + unwrapped = [] + for v in self: + if recursive: + unwrapped.append(v.unwrap(recursive=recursive)) + else: + unwrapped.append(v) + return unwrapped + @property def discriminant(self) -> int: return 8 @@ -1323,7 +1332,14 @@ def __init__(self, value: "container.Container", trivia: Trivia): dict.__setitem__(self, k.key, v) def unwrap(self, recursive: bool = True): - pass + unwrapped = {} + for k in self: + if recursive: + unwrapped[k] = self[k].unwrap(recursive=recursive) + else: + unwrapped[k] = self[k] + + return unwrapped @property def value(self) -> "container.Container": @@ -1708,6 +1724,15 @@ def __init__( for table in body: self.append(table) + def unwrap(self, recursive: bool = True) -> str: + unwrapped = [] + for t in self._body: + if recursive: + unwrapped.append(t.unwrap(recursive=recursive)) + else: + unwrapped.append(t) + return unwrapped + @property def body(self) -> List[Table]: return self._body @@ -1799,6 +1824,9 @@ class Null(Item): def __init__(self) -> None: pass + def unwrap(self, recursive: bool = True) -> str: + return None + @property def discriminant(self) -> int: return -1 From e46868c864e11107030350948aa4f1d0ceb96b6a Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Mon, 18 Apr 2022 20:53:09 -0700 Subject: [PATCH 04/22] remove dangling 'def' --- tomlkit/items.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tomlkit/items.py b/tomlkit/items.py index 7eab7a8..f2051ae 100644 --- a/tomlkit/items.py +++ b/tomlkit/items.py @@ -538,8 +538,6 @@ def __reduce__(self): def __reduce_ex__(self, protocol): return self.__class__, self._getstate(protocol) - def - class Whitespace(Item): """ From ca434ea423ef7d2ed38273e5d7a6db5c886c1c91 Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Wed, 27 Apr 2022 12:04:01 -0700 Subject: [PATCH 05/22] Container loops through items() instead of _body --- tomlkit/container.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tomlkit/container.py b/tomlkit/container.py index c0da383..7ce6a8b 100644 --- a/tomlkit/container.py +++ b/tomlkit/container.py @@ -48,7 +48,7 @@ def body(self) -> List[Tuple[Optional[Key], Item]]: def unwrap(self, recursive: bool = True) -> str: unwrapped = {} - for k, v in self._body: + for k, v in self.items(): if k is None: continue From 401e8da4bc4e82244e2f715672417610f5bdd5ec Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Wed, 27 Apr 2022 12:04:31 -0700 Subject: [PATCH 06/22] add Integer and Item unit tests --- tests/test_items.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/test_items.py b/tests/test_items.py index 057ed46..476a922 100644 --- a/tests/test_items.py +++ b/tests/test_items.py @@ -69,6 +69,24 @@ def dst(self, dt): return UTC() +def test_item_base_has_no_unwrap(): + trivia = Trivia(indent='\t', comment_ws=' ', comment='For unit test') + item = items.Item(trivia) + try: + item.unwrap() + except NotImplementedError: + pass + else: + raise AssertionError("`items.Item` should not implement `unwrap`") + +def test_integer_unwrap(): + i = item(666) + + i_unwrapped = i.unwrap() + + assert type(i) == Integer + assert type(i_unwrapped) != Integer + def test_key_comparison(): k = Key("foo") From e5724f953f36ae3e634884c5a0a2d4cdae690285 Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Wed, 27 Apr 2022 12:51:16 -0700 Subject: [PATCH 07/22] added passing tests for everything up to Array --- tests/test_items.py | 56 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/tests/test_items.py b/tests/test_items.py index 476a922..74c10ad 100644 --- a/tests/test_items.py +++ b/tests/test_items.py @@ -15,12 +15,18 @@ 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 item from tomlkit.parser import Parser @@ -71,7 +77,7 @@ def dst(self, dt): def test_item_base_has_no_unwrap(): trivia = Trivia(indent='\t', comment_ws=' ', comment='For unit test') - item = items.Item(trivia) + item = Item(trivia) try: item.unwrap() except NotImplementedError: @@ -79,13 +85,51 @@ def test_item_base_has_no_unwrap(): else: raise AssertionError("`items.Item` should not implement `unwrap`") -def test_integer_unwrap(): - i = item(666) +def assert_is_ppo(v_unwrapped, TomlkitType, unwrappedType): + assert type(v_unwrapped) != TomlkitType + assert type(v_unwrapped) == unwrappedType + +def elementary_test(v, TomlkitType, unwrappedType): + v_unwrapped = v.unwrap() + assert type(v) == TomlkitType + assert type(v) != unwrappedType + assert_is_ppo(v_unwrapped, TomlkitType, unwrappedType) - i_unwrapped = i.unwrap() +def elementary_fail(v, TomlkitType, unwrappedType): + v_unwrapped = v.unwrap() + assert type(v) == TomlkitType + assert type(v_unwrapped) == TomlkitType + assert type(v_unwrapped) == unwrappedType + assert type(v) != unwrappedType - assert type(i) == Integer - assert type(i_unwrapped) != Integer +def test_integer_unwrap(): + elementary_test(item(666), Integer, int) +def test_float_unwrap(): + elementary_test(item(2.78), Float, float) +def test_false_unwrap(): + elementary_test(item(False), Bool, bool) +def test_true_unwrap(): + elementary_test(item(True), Bool, bool) +def test_datetime_unwrap(): + dt=datetime.utcnow() + elementary_test(item(dt), DateTime, datetime) +def test_time_unwrap(): + t=time(3, 8, 14) + elementary_test(item(t), Time, time) +def test_date_unwrap(): + d=date.today() + elementary_test(item(d), Date, 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 type(a_unwrapped) == list + assert_is_ppo(a_unwrapped[0], Integer, int) + assert_is_ppo(a_unwrapped[1], Float, float) + assert_is_ppo(a_unwrapped[2], Bool, bool) def test_key_comparison(): k = Key("foo") From cd1256096b76b855a629d6d59ba69be5f4fba315 Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Thu, 28 Apr 2022 04:24:41 -0700 Subject: [PATCH 08/22] remove recursive option --- tomlkit/check.py | 21 +++++++++++++++++++++ tomlkit/container.py | 10 +++++----- tomlkit/items.py | 37 +++++++++++++++++++------------------ 3 files changed, 45 insertions(+), 23 deletions(-) create mode 100644 tomlkit/check.py diff --git a/tomlkit/check.py b/tomlkit/check.py new file mode 100644 index 0000000..b0b3590 --- /dev/null +++ b/tomlkit/check.py @@ -0,0 +1,21 @@ +def is_ppo(v): + from datetime import date + from datetime import datetime + from datetime import time + from datetime import timedelta + PPO_TYPES = [int, bool, float, date, time, datetime, list, tuple, dict, str] + if type(v) in PPO_TYPES: + return True + return False + +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 diff --git a/tomlkit/container.py b/tomlkit/container.py index 7ce6a8b..473f96d 100644 --- a/tomlkit/container.py +++ b/tomlkit/container.py @@ -46,7 +46,7 @@ def __init__(self, parsed: bool = False) -> None: def body(self) -> List[Tuple[Optional[Key], Item]]: return self._body - def unwrap(self, recursive: bool = True) -> str: + def unwrap(self) -> str: unwrapped = {} for k, v in self.items(): if k is None: @@ -56,12 +56,12 @@ def unwrap(self, recursive: bool = True) -> str: v = v.value if isinstance(v, Container): - v = v.unwrap(recursive=recursive) + v = v.unwrap() if k in unwrapped: merge_dicts(unwrapped[k], v) else: - unwrapped[k] = v.unwrap(recursive=recursive) + unwrapped[k] = v.unwrap() return unwrapped @@ -815,8 +815,8 @@ def __init__(self, container: Container, indices: Tuple[int]) -> None: if k is not None: dict.__setitem__(self, k.key, v) - def unwrap(self, recursive: bool = True) -> str: - return self._internal_container.unwrap(recursive=recursive) + def unwrap(self) -> str: + return self._internal_container.unwrap() @property def value(self): diff --git a/tomlkit/items.py b/tomlkit/items.py index f2051ae..afed96a 100644 --- a/tomlkit/items.py +++ b/tomlkit/items.py @@ -29,6 +29,7 @@ from ._utils import escape_string from .exceptions import InvalidStringError from .toml_char import TOMLChar +from .check import is_tomlkit if TYPE_CHECKING: # pragma: no cover @@ -492,7 +493,7 @@ def as_string(self) -> str: """The TOML representation""" raise NotImplementedError() - def unwrap(self, recursive: bool = True): + def unwrap(self): """Returns as pure python object (ppo)""" raise NotImplementedError() @@ -614,7 +615,7 @@ def __init__(self, _: int, trivia: Trivia, raw: str) -> None: if re.match(r"^[+\-]\d+$", raw): self._sign = True - def unwrap(self, recursive: bool = True) -> int: + def unwrap(self) -> int: return int(self) @property @@ -685,7 +686,7 @@ def __init__(self, _: float, trivia: Trivia, raw: str) -> None: if re.match(r"^[+\-].+$", raw): self._sign = True - def unwrap(self, recursive: bool = True) -> float: + def unwrap(self) -> float: return float(self) @property @@ -749,7 +750,7 @@ def __init__(self, t: int, trivia: Trivia) -> None: self._value = bool(t) - def unwrap(self, recursive: bool = True) -> bool: + def unwrap(self) -> bool: return bool(self) @property @@ -834,7 +835,7 @@ def __init__( self._raw = raw or self.isoformat() - def unwrap(self, recursive: bool = True) -> datetime: + def unwrap(self) -> datetime: (year, month, day, hour, minute, second, microsecond, tzinfo, _, _) = self._getstate() return datetime(year, month, day, hour, minute, second, microsecond, tzinfo) @@ -941,7 +942,7 @@ def __init__( self._raw = raw - def unwrap(self, recursive: bool = True) -> date: + def unwrap(self) -> date: (year, month, day, _, _) = self._getstate() return date(year, month, day) @@ -1017,7 +1018,7 @@ def __init__( self._raw = raw - def unwrap(self, recursive: bool = True) -> datetime: + def unwrap(self) -> datetime: (hour, minute, second, microsecond, tzinfo, _, _) = self._getstate() return time(hour, minute, second, microsecond, tzinfo) @@ -1076,11 +1077,11 @@ def __init__(self, value: list, trivia: Trivia, multiline: bool = False) -> None self._multiline = multiline self._reindex() - def unwrap(self, recursive: bool = True) -> str: + def unwrap(self) -> str: unwrapped = [] for v in self: - if recursive: - unwrapped.append(v.unwrap(recursive=recursive)) + if is_tomlkit(v): + unwrapped.append(v.unwrap()) else: unwrapped.append(v) return unwrapped @@ -1329,11 +1330,11 @@ def __init__(self, value: "container.Container", trivia: Trivia): if k is not None: dict.__setitem__(self, k.key, v) - def unwrap(self, recursive: bool = True): + def unwrap(self): unwrapped = {} for k in self: - if recursive: - unwrapped[k] = self[k].unwrap(recursive=recursive) + if is_tomlkit(v): + unwrapped[k] = self[k].unwrap() else: unwrapped[k] = self[k] @@ -1661,7 +1662,7 @@ def __init__(self, t: StringType, _: str, original: str, trivia: Trivia) -> None self._t = t self._original = original - def unwrap(self, recursive: bool = True) -> str: + def unwrap(self) -> str: return self.as_string() @property @@ -1722,11 +1723,11 @@ def __init__( for table in body: self.append(table) - def unwrap(self, recursive: bool = True) -> str: + def unwrap(self) -> str: unwrapped = [] for t in self._body: - if recursive: - unwrapped.append(t.unwrap(recursive=recursive)) + if is_tomlkit(v): + unwrapped.append(t.unwrap()) else: unwrapped.append(t) return unwrapped @@ -1822,7 +1823,7 @@ class Null(Item): def __init__(self) -> None: pass - def unwrap(self, recursive: bool = True) -> str: + def unwrap(self) -> str: return None @property From 2205012fcd00e4a278eef01fdadee5a45a342b49 Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Thu, 28 Apr 2022 04:26:24 -0700 Subject: [PATCH 09/22] remove unused is_ppo function --- tomlkit/check.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tomlkit/check.py b/tomlkit/check.py index b0b3590..daf1920 100644 --- a/tomlkit/check.py +++ b/tomlkit/check.py @@ -1,13 +1,3 @@ -def is_ppo(v): - from datetime import date - from datetime import datetime - from datetime import time - from datetime import timedelta - PPO_TYPES = [int, bool, float, date, time, datetime, list, tuple, dict, str] - if type(v) in PPO_TYPES: - return True - return False - def is_tomlkit(v): from .items import Item as _Item from .container import Container From 465fe763a055ae7d41ec7d197af05f604d893c65 Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Thu, 28 Apr 2022 05:00:34 -0700 Subject: [PATCH 10/22] refactor Container unwrap to reuse code --- tomlkit/container.py | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/tomlkit/container.py b/tomlkit/container.py index 473f96d..88d1580 100644 --- a/tomlkit/container.py +++ b/tomlkit/container.py @@ -46,22 +46,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 + def _unwrap_inner(self, k, v, d): + if k is None: + return - k = k.key + k = k.key + v = v.value + + if isinstance(v, Container): v = v.value - if isinstance(v, Container): - v = v.unwrap() + if k in d: + merge_dicts(d[k], v) + else: + d[k] = v - if k in unwrapped: - merge_dicts(unwrapped[k], v) - else: - unwrapped[k] = v.unwrap() + def unwrap(self) -> str: + unwrapped = {} + for k, v in self.items(): + self._unwrap_inner(k, v, unwrapped) return unwrapped @@ -69,19 +72,7 @@ def unwrap(self) -> str: def value(self) -> Dict[Any, Any]: d = {} for k, v in self._body: - if k is None: - continue - - k = k.key - v = v.value - - if isinstance(v, Container): - v = v.value - - if k in d: - merge_dicts(d[k], v) - else: - d[k] = v + self._unwrap_inner(k, v, d) return d From c132ce10bc2270487dd6461763c3ed77f65efbe6 Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Thu, 28 Apr 2022 05:01:28 -0700 Subject: [PATCH 11/22] add AbstractTable test --- tests/test_items.py | 13 +++++++++++++ tomlkit/items.py | 11 ++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/tests/test_items.py b/tests/test_items.py index 74c10ad..a313ede 100644 --- a/tests/test_items.py +++ b/tests/test_items.py @@ -29,6 +29,7 @@ from tomlkit.items import Item from tomlkit.items import item from tomlkit.parser import Parser +from tomlkit.check import is_tomlkit @pytest.fixture() @@ -130,6 +131,18 @@ def test_array_unwrap(): assert_is_ppo(a_unwrapped[0], Integer, int) assert_is_ppo(a_unwrapped[1], Float, float) assert_is_ppo(a_unwrapped[2], Bool, 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() + assert type(table_unwrapped) == dict + sub_table = table_unwrapped["table"] + assert type(sub_table) == dict + for (k, v) in zip(sub_table.keys(), sub_table): + assert type(k) == str + assert type(v) == str def test_key_comparison(): k = Key("foo") diff --git a/tomlkit/items.py b/tomlkit/items.py index afed96a..52e2efd 100644 --- a/tomlkit/items.py +++ b/tomlkit/items.py @@ -1333,10 +1333,15 @@ def __init__(self, value: "container.Container", trivia: Trivia): def unwrap(self): unwrapped = {} for k in self: - if is_tomlkit(v): - unwrapped[k] = self[k].unwrap() + if is_tomlkit(k): + nk = k.unwrap() + else: + nk = k + if is_tomlkit(self[k]): + nv = self[k].unwrap() else: - unwrapped[k] = self[k] + nv = self[k] + unwrapped[nk] = nv return unwrapped From a13db5e976e423f4035613885d6aa7755c647c6c Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Thu, 28 Apr 2022 05:19:18 -0700 Subject: [PATCH 12/22] add string, null, and aot tests --- tests/test_items.py | 18 ++++++++++++++++++ tomlkit/items.py | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/test_items.py b/tests/test_items.py index a313ede..96da241 100644 --- a/tests/test_items.py +++ b/tests/test_items.py @@ -28,6 +28,7 @@ from tomlkit.items import Trivia from tomlkit.items import Item from tomlkit.items import item +from tomlkit.items import Null from tomlkit.parser import Parser from tomlkit.check import is_tomlkit @@ -114,6 +115,23 @@ def test_true_unwrap(): def test_datetime_unwrap(): dt=datetime.utcnow() elementary_test(item(dt), DateTime, datetime) +def test_string_unwrap(): + elementary_test(item("hello"), String, str) +def test_null_unwrap(): + n = Null() + elementary_test(n, Null, type(None)) +def test_aot_unwrap(): + d = item([{"a": "A"}, {"b": "B"}]) + assert is_tomlkit(d) + unwrapped = d.unwrap() + assert type(unwrapped) == list + for de in unwrapped: + assert type(de) == dict + for k in de: + v = de[k] + assert type(k) == str + assert type(v) == str + def test_time_unwrap(): t=time(3, 8, 14) elementary_test(item(t), Time, time) diff --git a/tomlkit/items.py b/tomlkit/items.py index 52e2efd..83e4e37 100644 --- a/tomlkit/items.py +++ b/tomlkit/items.py @@ -1731,7 +1731,7 @@ def __init__( def unwrap(self) -> str: unwrapped = [] for t in self._body: - if is_tomlkit(v): + if is_tomlkit(t): unwrapped.append(t.unwrap()) else: unwrapped.append(t) From 1938f2f8715219bcab8651ecf55cd0c7fb0b706b Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Thu, 28 Apr 2022 06:08:50 -0700 Subject: [PATCH 13/22] add test for Container --- tests/test_toml_document.py | 13 +++++++++++ tomlkit/container.py | 45 +++++++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/tests/test_toml_document.py b/tests/test_toml_document.py index c350984..669fd9f 100644 --- a/tests/test_toml_document.py +++ b/tests/test_toml_document.py @@ -153,6 +153,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 type(unwrapped) == dict + assert type(list(unwrapped.keys())[0]) == str + assert type(unwrapped["tool"]) == dict + assert type(list(unwrapped["tool"].keys())[0]) == str + assert type(unwrapped["tool"]["poetry"]["name"]) == str + def test_toml_document_with_dotted_keys(example): content = example("0.5.0") diff --git a/tomlkit/container.py b/tomlkit/container.py index 88d1580..7137c10 100644 --- a/tomlkit/container.py +++ b/tomlkit/container.py @@ -25,6 +25,8 @@ from .items import _CustomDict from .items import item as _item +from .check import is_tomlkit + _NOT_SET = object() @@ -46,25 +48,22 @@ def __init__(self, parsed: bool = False) -> None: def body(self) -> List[Tuple[Optional[Key], Item]]: return self._body - def _unwrap_inner(self, k, v, d): - if k is None: - return - - k = k.key - v = v.value - - if isinstance(v, Container): - v = v.value - - if k in d: - merge_dicts(d[k], v) - else: - d[k] = v - def unwrap(self) -> str: unwrapped = {} for k, v in self.items(): - self._unwrap_inner(k, v, unwrapped) + if k is None: + continue + + if not type(k) == str: + k = k.key + + if not type(v) == str: + v = v.unwrap() + + if k in unwrapped: + merge_dicts(unwrapped[k], v) + else: + unwrapped[k] = v return unwrapped @@ -72,7 +71,19 @@ def unwrap(self) -> str: def value(self) -> Dict[Any, Any]: d = {} for k, v in self._body: - self._unwrap_inner(k, v, d) + if k is None: + continue + + k = k.key + v = v.value + + if isinstance(v, Container): + v = v.value + + if k in d: + merge_dicts(d[k], v) + else: + d[k] = v return d From a936a4495e7b6b3f11aefce91f4dc5ede89015e5 Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Mon, 2 May 2022 00:39:56 -0700 Subject: [PATCH 14/22] type(..) to isinstance(..) in Container unwrap --- tomlkit/container.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tomlkit/container.py b/tomlkit/container.py index 7137c10..c7a8862 100644 --- a/tomlkit/container.py +++ b/tomlkit/container.py @@ -54,10 +54,10 @@ def unwrap(self) -> str: if k is None: continue - if not type(k) == str: + if not isinstance(k, str): k = k.key - if not type(v) == str: + if not isinstance(v, str): v = v.unwrap() if k in unwrapped: From 21ec17b49438fdc1f9cff7db27c27786c9376654 Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Mon, 2 May 2022 01:07:37 -0700 Subject: [PATCH 15/22] try/catch ensure v has unwrap in Container.unwrap --- tomlkit/container.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tomlkit/container.py b/tomlkit/container.py index c7a8862..22cb483 100644 --- a/tomlkit/container.py +++ b/tomlkit/container.py @@ -57,8 +57,10 @@ def unwrap(self) -> str: if not isinstance(k, str): k = k.key - if not isinstance(v, str): + try: v = v.unwrap() + except AttributeError: + pass if k in unwrapped: merge_dicts(unwrapped[k], v) From f91566acb7894ae56ad843b30b5f894a1b0c4586 Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Fri, 20 May 2022 09:59:34 -0700 Subject: [PATCH 16/22] replace 'type' with 'isinstance' in test_items.py --- tests/test_items.py | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/tests/test_items.py b/tests/test_items.py index 96da241..2a63b9d 100644 --- a/tests/test_items.py +++ b/tests/test_items.py @@ -27,6 +27,7 @@ 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 @@ -88,15 +89,16 @@ def test_item_base_has_no_unwrap(): raise AssertionError("`items.Item` should not implement `unwrap`") def assert_is_ppo(v_unwrapped, TomlkitType, unwrappedType): - assert type(v_unwrapped) != TomlkitType - assert type(v_unwrapped) == unwrappedType + assert not isinstance(v_unwrapped, TomlkitType) + assert isinstance(v_unwrapped, unwrappedType) def elementary_test(v, TomlkitType, unwrappedType): v_unwrapped = v.unwrap() - assert type(v) == TomlkitType - assert type(v) != unwrappedType + assert isinstance(v, TomlkitType) assert_is_ppo(v_unwrapped, TomlkitType, unwrappedType) +# a check thats designed to fail to make sure the tests works +# TODO Remove before merge (maybe?) def elementary_fail(v, TomlkitType, unwrappedType): v_unwrapped = v.unwrap() assert type(v) == TomlkitType @@ -124,13 +126,13 @@ def test_aot_unwrap(): d = item([{"a": "A"}, {"b": "B"}]) assert is_tomlkit(d) unwrapped = d.unwrap() - assert type(unwrapped) == list - for de in unwrapped: - assert type(de) == dict - for k in de: - v = de[k] - assert type(k) == str - assert type(v) == str + assert_is_ppo(unwrapped, AoT, list) + for du, dw in zip(unwrapped, d): + assert_is_ppo(du, Table, dict) + for ku in du: + vu = du[ku] + assert_is_ppo(ku, String, str) + assert_is_ppo(vu, String, str) def test_time_unwrap(): t=time(3, 8, 14) @@ -145,7 +147,7 @@ def test_array_unwrap(): b=item(False) a=Array([i, f, b], trivia) a_unwrapped=a.unwrap() - assert type(a_unwrapped) == list + assert_is_ppo(a_unwrapped, Array, list) assert_is_ppo(a_unwrapped[0], Integer, int) assert_is_ppo(a_unwrapped[1], Float, float) assert_is_ppo(a_unwrapped[2], Bool, bool) @@ -155,12 +157,13 @@ def test_abstract_table_unwrap(): assert is_tomlkit(super_table["table"]) table_unwrapped = super_table.unwrap() - assert type(table_unwrapped) == dict sub_table = table_unwrapped["table"] - assert type(sub_table) == dict - for (k, v) in zip(sub_table.keys(), sub_table): - assert type(k) == str - assert type(v) == str + assert_is_ppo(table_unwrapped, Table, dict) + assert_is_ppo(sub_table, Table, dict) + for ku in sub_table: + vu = sub_table[ku] + assert_is_ppo(ku, String, str) + assert_is_ppo(vu, String, str) def test_key_comparison(): k = Key("foo") From b70b31244d24df4f9e3cc7fa108682f848847256 Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Fri, 20 May 2022 10:59:39 -0700 Subject: [PATCH 17/22] refactor assert_is_ppo to pass only ppo type --- tests/test_items.py | 54 ++++++++++++++++++++------------------------- tests/util.py | 53 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 30 deletions(-) create mode 100644 tests/util.py diff --git a/tests/test_items.py b/tests/test_items.py index 2a63b9d..03b9bfd 100644 --- a/tests/test_items.py +++ b/tests/test_items.py @@ -8,6 +8,9 @@ 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 @@ -88,15 +91,6 @@ def test_item_base_has_no_unwrap(): else: raise AssertionError("`items.Item` should not implement `unwrap`") -def assert_is_ppo(v_unwrapped, TomlkitType, unwrappedType): - assert not isinstance(v_unwrapped, TomlkitType) - assert isinstance(v_unwrapped, unwrappedType) - -def elementary_test(v, TomlkitType, unwrappedType): - v_unwrapped = v.unwrap() - assert isinstance(v, TomlkitType) - assert_is_ppo(v_unwrapped, TomlkitType, unwrappedType) - # a check thats designed to fail to make sure the tests works # TODO Remove before merge (maybe?) def elementary_fail(v, TomlkitType, unwrappedType): @@ -107,39 +101,39 @@ def elementary_fail(v, TomlkitType, unwrappedType): assert type(v) != unwrappedType def test_integer_unwrap(): - elementary_test(item(666), Integer, int) + elementary_test(item(666), int) def test_float_unwrap(): - elementary_test(item(2.78), Float, float) + elementary_test(item(2.78), float) def test_false_unwrap(): - elementary_test(item(False), Bool, bool) + elementary_test(item(False), bool) def test_true_unwrap(): - elementary_test(item(True), Bool, bool) + elementary_test(item(True), bool) def test_datetime_unwrap(): dt=datetime.utcnow() - elementary_test(item(dt), DateTime, datetime) + elementary_test(item(dt), datetime) def test_string_unwrap(): - elementary_test(item("hello"), String, str) + elementary_test(item("hello"), str) def test_null_unwrap(): n = Null() - elementary_test(n, Null, type(None)) + 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, AoT, list) + assert_is_ppo(unwrapped, list) for du, dw in zip(unwrapped, d): - assert_is_ppo(du, Table, dict) + assert_is_ppo(du, dict) for ku in du: vu = du[ku] - assert_is_ppo(ku, String, str) - assert_is_ppo(vu, String, str) + assert_is_ppo(ku, str) + assert_is_ppo(vu, str) def test_time_unwrap(): t=time(3, 8, 14) - elementary_test(item(t), Time, time) + elementary_test(item(t), time) def test_date_unwrap(): d=date.today() - elementary_test(item(d), Date, date) + elementary_test(item(d), date) def test_array_unwrap(): trivia = Trivia(indent='\t', comment_ws=' ', comment='For unit test') i=item(666) @@ -147,10 +141,10 @@ def test_array_unwrap(): b=item(False) a=Array([i, f, b], trivia) a_unwrapped=a.unwrap() - assert_is_ppo(a_unwrapped, Array, list) - assert_is_ppo(a_unwrapped[0], Integer, int) - assert_is_ppo(a_unwrapped[1], Float, float) - assert_is_ppo(a_unwrapped[2], Bool, bool) + 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"}) @@ -158,12 +152,12 @@ def test_abstract_table_unwrap(): table_unwrapped = super_table.unwrap() sub_table = table_unwrapped["table"] - assert_is_ppo(table_unwrapped, Table, dict) - assert_is_ppo(sub_table, Table, dict) + 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, String, str) - assert_is_ppo(vu, String, str) + assert_is_ppo(ku, str) + assert_is_ppo(vu, str) def test_key_comparison(): k = Key("foo") diff --git a/tests/util.py b/tests/util.py new file mode 100644 index 0000000..5dc9381 --- /dev/null +++ b/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) From f4f03318ac4191744696c3aa2504a652323c6531 Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Fri, 20 May 2022 11:03:29 -0700 Subject: [PATCH 18/22] refactory test_document_is_a_dict to not call 'type' --- tests/test_toml_document.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/test_toml_document.py b/tests/test_toml_document.py index 669fd9f..784e274 100644 --- a/tests/test_toml_document.py +++ b/tests/test_toml_document.py @@ -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): @@ -160,11 +164,11 @@ def test_toml_document_unwrap(): doc = parse(content) unwrapped=doc.unwrap() - assert type(unwrapped) == dict - assert type(list(unwrapped.keys())[0]) == str - assert type(unwrapped["tool"]) == dict - assert type(list(unwrapped["tool"].keys())[0]) == str - assert type(unwrapped["tool"]["poetry"]["name"]) == str + 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): From b1b0c32e7b6e577d53e75706a2a6bd7159d02cd4 Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Fri, 20 May 2022 11:04:20 -0700 Subject: [PATCH 19/22] remove elementary_fail function --- tests/test_items.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/test_items.py b/tests/test_items.py index 03b9bfd..e1cec7e 100644 --- a/tests/test_items.py +++ b/tests/test_items.py @@ -91,15 +91,6 @@ def test_item_base_has_no_unwrap(): else: raise AssertionError("`items.Item` should not implement `unwrap`") -# a check thats designed to fail to make sure the tests works -# TODO Remove before merge (maybe?) -def elementary_fail(v, TomlkitType, unwrappedType): - v_unwrapped = v.unwrap() - assert type(v) == TomlkitType - assert type(v_unwrapped) == TomlkitType - assert type(v_unwrapped) == unwrappedType - assert type(v) != unwrappedType - def test_integer_unwrap(): elementary_test(item(666), int) def test_float_unwrap(): From a8ebf827e927582e5780ce8ff0db1071a9b1d212 Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Fri, 20 May 2022 11:57:13 -0700 Subject: [PATCH 20/22] minor change in Container unwrap method --- tomlkit/container.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tomlkit/container.py b/tomlkit/container.py index 22cb483..4951133 100644 --- a/tomlkit/container.py +++ b/tomlkit/container.py @@ -57,10 +57,8 @@ def unwrap(self) -> str: if not isinstance(k, str): k = k.key - try: + if isinstance(v, Item): v = v.unwrap() - except AttributeError: - pass if k in unwrapped: merge_dicts(unwrapped[k], v) From 3dd4036852be692f7605ed7856db11b89b15eeb4 Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Sat, 21 May 2022 03:25:00 -0700 Subject: [PATCH 21/22] use isinstance not is_tomlkit in AoT.unwrap --- tomlkit/items.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tomlkit/items.py b/tomlkit/items.py index 83e4e37..1f28155 100644 --- a/tomlkit/items.py +++ b/tomlkit/items.py @@ -1731,7 +1731,7 @@ def __init__( def unwrap(self) -> str: unwrapped = [] for t in self._body: - if is_tomlkit(t): + if isinstance(t, Item): unwrapped.append(t.unwrap()) else: unwrapped.append(t) From b84c13b48589156ed59e04d0dd48cafb3cf0513d Mon Sep 17 00:00:00 2001 From: Sami Abdul-Wahid Date: Sat, 21 May 2022 20:34:19 -0700 Subject: [PATCH 22/22] run pre-commit --- tests/test_items.py | 67 +++++++++++++++++++++++++------------ tests/test_toml_document.py | 9 ++--- tests/util.py | 22 +++++++----- tomlkit/check.py | 3 +- tomlkit/container.py | 3 +- tomlkit/items.py | 15 +++++++-- 6 files changed, 79 insertions(+), 40 deletions(-) diff --git a/tests/test_items.py b/tests/test_items.py index e1cec7e..e36a130 100644 --- a/tests/test_items.py +++ b/tests/test_items.py @@ -8,33 +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.check import is_tomlkit from tomlkit.exceptions import NonExistentKey +from tomlkit.items import AoT +from tomlkit.items import Array from tomlkit.items import Bool from tomlkit.items import Comment +from tomlkit.items import Date +from tomlkit.items import DateTime +from tomlkit.items import Float 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 Item from tomlkit.items import KeyType +from tomlkit.items import Null 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 Time 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 + +from .util import assert_is_ppo +from .util import elementary_test @pytest.fixture() @@ -82,7 +82,7 @@ def dst(self, dt): def test_item_base_has_no_unwrap(): - trivia = Trivia(indent='\t', comment_ws=' ', comment='For unit test') + trivia = Trivia(indent="\t", comment_ws=" ", comment="For unit test") item = Item(trivia) try: item.unwrap() @@ -91,22 +91,37 @@ def test_item_base_has_no_unwrap(): 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() + 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) @@ -119,23 +134,30 @@ def test_aot_unwrap(): assert_is_ppo(ku, str) assert_is_ppo(vu, str) + def test_time_unwrap(): - t=time(3, 8, 14) + t = time(3, 8, 14) elementary_test(item(t), time) + + def test_date_unwrap(): - d=date.today() + 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() + 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"}) @@ -150,6 +172,7 @@ def test_abstract_table_unwrap(): assert_is_ppo(ku, str) assert_is_ppo(vu, str) + def test_key_comparison(): k = Key("foo") diff --git a/tests/test_toml_document.py b/tests/test_toml_document.py index 784e274..f2e57c9 100644 --- a/tests/test_toml_document.py +++ b/tests/test_toml_document.py @@ -9,9 +9,6 @@ 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 @@ -19,6 +16,9 @@ from tomlkit.exceptions import NonExistentKey from tomlkit.toml_document import TOMLDocument +from .util import assert_is_ppo +from .util import elementary_test + def test_document_is_a_dict(example): content = example("example") @@ -157,13 +157,14 @@ 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() + unwrapped = doc.unwrap() assert_is_ppo(unwrapped, dict) assert_is_ppo(list(unwrapped.keys())[0], str) assert_is_ppo(unwrapped["tool"], dict) diff --git a/tests/util.py b/tests/util.py index 5dc9381..3a4c758 100644 --- a/tests/util.py +++ b/tests/util.py @@ -1,23 +1,24 @@ +from tomlkit.items import AoT +from tomlkit.items import Array from tomlkit.items import Bool from tomlkit.items import Comment +from tomlkit.items import Date +from tomlkit.items import DateTime +from tomlkit.items import Float 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 Item from tomlkit.items import KeyType +from tomlkit.items import Null 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 Time 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, @@ -37,17 +38,20 @@ Item, AoT, Null, - TOMLDocument + 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) diff --git a/tomlkit/check.py b/tomlkit/check.py index daf1920..6d9327a 100644 --- a/tomlkit/check.py +++ b/tomlkit/check.py @@ -1,7 +1,8 @@ def is_tomlkit(v): - from .items import Item as _Item from .container import Container from .container import OutOfOrderTableProxy + from .items import Item as _Item + if isinstance(v, _Item): return True if isinstance(v, Container): diff --git a/tomlkit/container.py b/tomlkit/container.py index 4951133..5b03d5e 100644 --- a/tomlkit/container.py +++ b/tomlkit/container.py @@ -10,6 +10,7 @@ from ._compat import decode from ._utils import merge_dicts +from .check import is_tomlkit from .exceptions import KeyAlreadyPresent from .exceptions import NonExistentKey from .exceptions import TOMLKitError @@ -25,8 +26,6 @@ from .items import _CustomDict from .items import item as _item -from .check import is_tomlkit - _NOT_SET = object() diff --git a/tomlkit/items.py b/tomlkit/items.py index 1f28155..7bf88f6 100644 --- a/tomlkit/items.py +++ b/tomlkit/items.py @@ -27,9 +27,9 @@ from ._compat import decode from ._utils import CONTROL_CHARS from ._utils import escape_string +from .check import is_tomlkit from .exceptions import InvalidStringError from .toml_char import TOMLChar -from .check import is_tomlkit if TYPE_CHECKING: # pragma: no cover @@ -836,7 +836,18 @@ def __init__( self._raw = raw or self.isoformat() def unwrap(self) -> datetime: - (year, month, day, hour, minute, second, microsecond, tzinfo, _, _) = self._getstate() + ( + year, + month, + day, + hour, + minute, + second, + microsecond, + tzinfo, + _, + _, + ) = self._getstate() return datetime(year, month, day, hour, minute, second, microsecond, tzinfo) @property