17db96d56Sopenharmony_ci# SPDX-License-Identifier: MIT
27db96d56Sopenharmony_ci# SPDX-FileCopyrightText: 2021 Taneli Hukkinen
37db96d56Sopenharmony_ci# Licensed to PSF under a Contributor Agreement.
47db96d56Sopenharmony_ci
57db96d56Sopenharmony_ciimport copy
67db96d56Sopenharmony_ciimport datetime
77db96d56Sopenharmony_cifrom decimal import Decimal as D
87db96d56Sopenharmony_cifrom pathlib import Path
97db96d56Sopenharmony_ciimport sys
107db96d56Sopenharmony_ciimport tempfile
117db96d56Sopenharmony_ciimport unittest
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_cifrom . import tomllib
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ciclass TestMiscellaneous(unittest.TestCase):
177db96d56Sopenharmony_ci    def test_load(self):
187db96d56Sopenharmony_ci        content = "one=1 \n two='two' \n arr=[]"
197db96d56Sopenharmony_ci        expected = {"one": 1, "two": "two", "arr": []}
207db96d56Sopenharmony_ci        with tempfile.TemporaryDirectory() as tmp_dir_path:
217db96d56Sopenharmony_ci            file_path = Path(tmp_dir_path) / "test.toml"
227db96d56Sopenharmony_ci            file_path.write_text(content)
237db96d56Sopenharmony_ci
247db96d56Sopenharmony_ci            with open(file_path, "rb") as bin_f:
257db96d56Sopenharmony_ci                actual = tomllib.load(bin_f)
267db96d56Sopenharmony_ci        self.assertEqual(actual, expected)
277db96d56Sopenharmony_ci
287db96d56Sopenharmony_ci    def test_incorrect_load(self):
297db96d56Sopenharmony_ci        content = "one=1"
307db96d56Sopenharmony_ci        with tempfile.TemporaryDirectory() as tmp_dir_path:
317db96d56Sopenharmony_ci            file_path = Path(tmp_dir_path) / "test.toml"
327db96d56Sopenharmony_ci            file_path.write_text(content)
337db96d56Sopenharmony_ci
347db96d56Sopenharmony_ci            with open(file_path, "r") as txt_f:
357db96d56Sopenharmony_ci                with self.assertRaises(TypeError):
367db96d56Sopenharmony_ci                    tomllib.load(txt_f)  # type: ignore[arg-type]
377db96d56Sopenharmony_ci
387db96d56Sopenharmony_ci    def test_parse_float(self):
397db96d56Sopenharmony_ci        doc = """
407db96d56Sopenharmony_ci              val=0.1
417db96d56Sopenharmony_ci              biggest1=inf
427db96d56Sopenharmony_ci              biggest2=+inf
437db96d56Sopenharmony_ci              smallest=-inf
447db96d56Sopenharmony_ci              notnum1=nan
457db96d56Sopenharmony_ci              notnum2=-nan
467db96d56Sopenharmony_ci              notnum3=+nan
477db96d56Sopenharmony_ci              """
487db96d56Sopenharmony_ci        obj = tomllib.loads(doc, parse_float=D)
497db96d56Sopenharmony_ci        expected = {
507db96d56Sopenharmony_ci            "val": D("0.1"),
517db96d56Sopenharmony_ci            "biggest1": D("inf"),
527db96d56Sopenharmony_ci            "biggest2": D("inf"),
537db96d56Sopenharmony_ci            "smallest": D("-inf"),
547db96d56Sopenharmony_ci            "notnum1": D("nan"),
557db96d56Sopenharmony_ci            "notnum2": D("-nan"),
567db96d56Sopenharmony_ci            "notnum3": D("nan"),
577db96d56Sopenharmony_ci        }
587db96d56Sopenharmony_ci        for k, expected_val in expected.items():
597db96d56Sopenharmony_ci            actual_val = obj[k]
607db96d56Sopenharmony_ci            self.assertIsInstance(actual_val, D)
617db96d56Sopenharmony_ci            if actual_val.is_nan():
627db96d56Sopenharmony_ci                self.assertTrue(expected_val.is_nan())
637db96d56Sopenharmony_ci            else:
647db96d56Sopenharmony_ci                self.assertEqual(actual_val, expected_val)
657db96d56Sopenharmony_ci
667db96d56Sopenharmony_ci    def test_deepcopy(self):
677db96d56Sopenharmony_ci        doc = """
687db96d56Sopenharmony_ci              [bliibaa.diibaa]
697db96d56Sopenharmony_ci              offsettime=[1979-05-27T00:32:00.999999-07:00]
707db96d56Sopenharmony_ci              """
717db96d56Sopenharmony_ci        obj = tomllib.loads(doc)
727db96d56Sopenharmony_ci        obj_copy = copy.deepcopy(obj)
737db96d56Sopenharmony_ci        self.assertEqual(obj_copy, obj)
747db96d56Sopenharmony_ci        expected_obj = {
757db96d56Sopenharmony_ci            "bliibaa": {
767db96d56Sopenharmony_ci                "diibaa": {
777db96d56Sopenharmony_ci                    "offsettime": [
787db96d56Sopenharmony_ci                        datetime.datetime(
797db96d56Sopenharmony_ci                            1979,
807db96d56Sopenharmony_ci                            5,
817db96d56Sopenharmony_ci                            27,
827db96d56Sopenharmony_ci                            0,
837db96d56Sopenharmony_ci                            32,
847db96d56Sopenharmony_ci                            0,
857db96d56Sopenharmony_ci                            999999,
867db96d56Sopenharmony_ci                            tzinfo=datetime.timezone(datetime.timedelta(hours=-7)),
877db96d56Sopenharmony_ci                        )
887db96d56Sopenharmony_ci                    ]
897db96d56Sopenharmony_ci                }
907db96d56Sopenharmony_ci            }
917db96d56Sopenharmony_ci        }
927db96d56Sopenharmony_ci        self.assertEqual(obj_copy, expected_obj)
937db96d56Sopenharmony_ci
947db96d56Sopenharmony_ci    def test_inline_array_recursion_limit(self):
957db96d56Sopenharmony_ci        # 465 with default recursion limit
967db96d56Sopenharmony_ci        nest_count = int(sys.getrecursionlimit() * 0.465)
977db96d56Sopenharmony_ci        recursive_array_toml = "arr = " + nest_count * "[" + nest_count * "]"
987db96d56Sopenharmony_ci        tomllib.loads(recursive_array_toml)
997db96d56Sopenharmony_ci
1007db96d56Sopenharmony_ci    def test_inline_table_recursion_limit(self):
1017db96d56Sopenharmony_ci        # 310 with default recursion limit
1027db96d56Sopenharmony_ci        nest_count = int(sys.getrecursionlimit() * 0.31)
1037db96d56Sopenharmony_ci        recursive_table_toml = nest_count * "key = {" + nest_count * "}"
1047db96d56Sopenharmony_ci        tomllib.loads(recursive_table_toml)
105