PKcsēR1uôTTdom_toml-0.5.0.dist-info/WHEELWheel-Version: 1.0 Generator: whey (0.0.13) Root-Is-Purelib: true Tag: py3-none-any PKcsēR…&7LL!dom_toml-0.5.0.dist-info/METADATAMetadata-Version: 2.1 Name: dom-toml Version: 0.5.0 Summary: Dom's tools for Tom's Obvious, Minimal Language. Author-email: Dominic Davis-Foster License: MIT Keywords: configuration,serialize,toml Home-page: https://github.com/domdfcoding/dom_toml Project-URL: Issue Tracker, https://github.com/domdfcoding/dom_toml/issues Project-URL: Source Code, https://github.com/domdfcoding/dom_toml Project-URL: Documentation, https://dom_toml.readthedocs.io/en/latest Platform: Windows Platform: macOS Platform: Linux Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Typing :: Typed Requires-Python: >=3.6 Requires-Dist: domdf-python-tools>=2.7.0 Requires-Dist: toml>=0.10.2 Description-Content-Type: text/x-rst ######### dom_toml ######### .. start short_desc **Dom's tools for Tom's Obvious, Minimal Language.** .. end short_desc .. start shields .. list-table:: :stub-columns: 1 :widths: 10 90 * - Docs - |docs| |docs_check| * - Tests - |actions_linux| |actions_windows| |actions_macos| |coveralls| * - PyPI - |pypi-version| |supported-versions| |supported-implementations| |wheel| * - Anaconda - |conda-version| |conda-platform| * - Activity - |commits-latest| |commits-since| |maintained| |pypi-downloads| * - QA - |codefactor| |actions_flake8| |actions_mypy| * - Other - |license| |language| |requires| .. |docs| image:: https://img.shields.io/readthedocs/dom_toml/latest?logo=read-the-docs :target: https://dom_toml.readthedocs.io/en/latest :alt: Documentation Build Status .. |docs_check| image:: https://github.com/domdfcoding/dom_toml/workflows/Docs%20Check/badge.svg :target: https://github.com/domdfcoding/dom_toml/actions?query=workflow%3A%22Docs+Check%22 :alt: Docs Check Status .. |actions_linux| image:: https://github.com/domdfcoding/dom_toml/workflows/Linux/badge.svg :target: https://github.com/domdfcoding/dom_toml/actions?query=workflow%3A%22Linux%22 :alt: Linux Test Status .. |actions_windows| image:: https://github.com/domdfcoding/dom_toml/workflows/Windows/badge.svg :target: https://github.com/domdfcoding/dom_toml/actions?query=workflow%3A%22Windows%22 :alt: Windows Test Status .. |actions_macos| image:: https://github.com/domdfcoding/dom_toml/workflows/macOS/badge.svg :target: https://github.com/domdfcoding/dom_toml/actions?query=workflow%3A%22macOS%22 :alt: macOS Test Status .. |actions_flake8| image:: https://github.com/domdfcoding/dom_toml/workflows/Flake8/badge.svg :target: https://github.com/domdfcoding/dom_toml/actions?query=workflow%3A%22Flake8%22 :alt: Flake8 Status .. |actions_mypy| image:: https://github.com/domdfcoding/dom_toml/workflows/mypy/badge.svg :target: https://github.com/domdfcoding/dom_toml/actions?query=workflow%3A%22mypy%22 :alt: mypy status .. |requires| image:: https://requires.io/github/domdfcoding/dom_toml/requirements.svg?branch=master :target: https://requires.io/github/domdfcoding/dom_toml/requirements/?branch=master :alt: Requirements Status .. |coveralls| image:: https://img.shields.io/coveralls/github/domdfcoding/dom_toml/master?logo=coveralls :target: https://coveralls.io/github/domdfcoding/dom_toml?branch=master :alt: Coverage .. |codefactor| image:: https://img.shields.io/codefactor/grade/github/domdfcoding/dom_toml?logo=codefactor :target: https://www.codefactor.io/repository/github/domdfcoding/dom_toml :alt: CodeFactor Grade .. |pypi-version| image:: https://img.shields.io/pypi/v/dom_toml :target: https://pypi.org/project/dom_toml/ :alt: PyPI - Package Version .. |supported-versions| image:: https://img.shields.io/pypi/pyversions/dom_toml?logo=python&logoColor=white :target: https://pypi.org/project/dom_toml/ :alt: PyPI - Supported Python Versions .. |supported-implementations| image:: https://img.shields.io/pypi/implementation/dom_toml :target: https://pypi.org/project/dom_toml/ :alt: PyPI - Supported Implementations .. |wheel| image:: https://img.shields.io/pypi/wheel/dom_toml :target: https://pypi.org/project/dom_toml/ :alt: PyPI - Wheel .. |conda-version| image:: https://img.shields.io/conda/v/domdfcoding/dom_toml?logo=anaconda :target: https://anaconda.org/domdfcoding/dom_toml :alt: Conda - Package Version .. |conda-platform| image:: https://img.shields.io/conda/pn/domdfcoding/dom_toml?label=conda%7Cplatform :target: https://anaconda.org/domdfcoding/dom_toml :alt: Conda - Platform .. |license| image:: https://img.shields.io/github/license/domdfcoding/dom_toml :target: https://github.com/domdfcoding/dom_toml/blob/master/LICENSE :alt: License .. |language| image:: https://img.shields.io/github/languages/top/domdfcoding/dom_toml :alt: GitHub top language .. |commits-since| image:: https://img.shields.io/github/commits-since/domdfcoding/dom_toml/v0.5.0 :target: https://github.com/domdfcoding/dom_toml/pulse :alt: GitHub commits since tagged version .. |commits-latest| image:: https://img.shields.io/github/last-commit/domdfcoding/dom_toml :target: https://github.com/domdfcoding/dom_toml/commit/master :alt: GitHub last commit .. |maintained| image:: https://img.shields.io/maintenance/yes/2021 :alt: Maintenance .. |pypi-downloads| image:: https://img.shields.io/pypi/dm/dom_toml :target: https://pypi.org/project/dom_toml/ :alt: PyPI - Downloads .. end shields Installation -------------- .. start installation ``dom_toml`` can be installed from PyPI or Anaconda. To install with ``pip``: .. code-block:: bash $ python -m pip install dom_toml To install with ``conda``: * First add the required channels .. code-block:: bash $ conda config --add channels https://conda.anaconda.org/conda-forge $ conda config --add channels https://conda.anaconda.org/domdfcoding * Then install .. code-block:: bash $ conda install dom_toml .. end installation PKcsēRÝlž}(( dom_toml-0.5.0.dist-info/LICENSECopyright (c) 2021 Dominic Davis-Foster Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PKcsēRŠÕqĸ &dom_toml-0.5.0.dist-info/top_level.txtdom_toml PKcsēR)dom_toml-0.5.0.dist-info/entry_points.txtPKcsēR-Œþššdom_toml/parser.py#!/usr/bin/env python3 # # parser.py """ Abstract base class for TOML configuration parsers. .. versionadded:: 0.2.0 """ # # Copyright ÂĐ 2021 Dominic Davis-Foster # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE # OR OTHER DEALINGS IN THE SOFTWARE. # # stdlib from abc import ABC, abstractmethod from typing import Any, Callable, ClassVar, Dict, Iterable, List, Tuple, Type, TypeVar, Union # 3rd party import toml __all__ = ["AbstractConfigParser", "BadConfigError", "construct_path"] TOML_TYPES = Any class BadConfigError(ValueError): """ Indicates an error in the TOML configuration. """ def construct_path(path: Iterable[str]) -> str: """ Construct a dotted path to a key. :param path: The path elements. """ return '.'.join([toml.dumps({elem: 0})[:-5] for elem in path]) _C = TypeVar("_C", bound=Callable) class AbstractConfigParser(ABC): """ Abstract base class for TOML configuration parsers. .. autoclasssumm:: AbstractConfigParser .. latex:clearpage:: """ defaults: ClassVar[Dict[str, Any]] """ A mapping of key names to default values. .. versionadded:: 0.3.0 """ factories: ClassVar[Dict[str, Callable[..., Any]]] """ A mapping of key names to default value factories. .. versionadded:: 0.3.0 .. note:: If both a default and a factory are defined for a key the factory takes precedence. .. note:: ``defaults`` and ``factories`` are reset for each subclass. To disable this behaviour set the ``inherit_defaults`` keyword argument on the class: .. code-block:: python class MyParser(AbstractConfigParser, inherit_default=True): pass """ def __init_subclass__(cls, **kwargs): if not kwargs.get("inherit_defaults", False): if "defaults" not in cls.__dict__: cls.defaults = {} if "factories" not in cls.__dict__: cls.factories = {} @staticmethod def assert_type( obj: Any, expected_type: Union[Type, Tuple[Type, ...]], path: Iterable[str], what: str = "type", ) -> None: """ Assert that ``obj`` is of type ``expected_type``, otherwise raise an error with a helpful message. :param obj: The object to check the type of. :param expected_type: The expected type. :param path: The elements of the path to ``obj`` in the TOML mapping. :param what: What ``obj`` is, e.g. ``'type'``, ``'value type'``. .. seealso:: :meth:`~.assert_value_type` and :meth:`~.assert_indexed_type` """ if not isinstance(obj, expected_type): name = construct_path(path) raise TypeError(f"Invalid {what} for {name!r}: expected {expected_type!r}, got {type(obj)!r}") @staticmethod def assert_indexed_type( obj: Any, expected_type: Union[Type, Tuple[Type, ...]], path: Iterable[str], idx: int = 0, ) -> None: """ Assert that ``obj`` is of type ``expected_type``, otherwise raise an error with a helpful message. :param obj: The object to check the type of. :param expected_type: The expected type. :param path: The elements of the path to ``obj`` in the TOML mapping. :param idx: The index of ``obj`` in the array. .. seealso:: :meth:`~.assert_type`, and :meth:`~.assert_value_type` """ if not isinstance(obj, expected_type): name = construct_path(path) + f"[{idx}]" raise TypeError(f"Invalid type for {name!r}: expected {expected_type!r}, got {type(obj)!r}") def assert_value_type( self, obj: Any, expected_type: Union[Type, Tuple[Type, ...]], path: Iterable[str], ): """ Assert that the value ``obj`` is of type ``expected_type``, otherwise raise an error with a helpful message. :param obj: The object to check the type of. :param expected_type: The expected type. :param path: The elements of the path to ``obj`` in the TOML mapping. .. seealso:: :meth:`~.assert_type` and :meth:`~.assert_indexed_type` """ self.assert_type(obj, expected_type, path, "value type") @property @abstractmethod def keys(self) -> List[str]: # pragma: no cover """ The keys to parse from the TOML file. """ raise NotImplementedError def parse( self, config: Dict[str, TOML_TYPES], set_defaults: bool = False, ) -> Dict[str, TOML_TYPES]: r""" Parse the TOML configuration. This function iterates over the list of keys given in :attr:`~.keys`. For each key, it searches for a method on the class called :file:`parse_{}`. * If the method exists, that method is called, passing the value as the only argument. The value returned from that method is included in the parsed configuration. The signature of those methods is: .. parsed-literal:: def visit_( self, config: :class:`typing.Dict`\[:class:`str`\, :py:obj:`typing.Any`\], ) -> :py:obj:`typing.Any`\: * If the method doesn't exist, the value is included in the parsed configuration unchanged. * Missing keys are ignored. Override this function in a subclass if you need that behaviour. Once all keys have been parsed the configuration is returned. :param config: :param set_defaults: If :py:obj:`True`, the values in :attr:`.AbstractConfigParser.defaults` and :attr:`.AbstractConfigParser.factories` will be set as defaults for the returned mapping. .. versionchanged:: 0.3.0 Added the ``set_defaults`` keyword argument. """ parsed_config = {} for key in self.keys: if key not in config: # Ignore absent values pass elif hasattr(self, f"parse_{key.replace('-', '_')}"): parsed_config[key] = getattr(self, f"parse_{key.replace('-', '_')}")(config) elif key in config: parsed_config[key] = config[key] if set_defaults: for key, value in self.defaults.items(): parsed_config.setdefault(key, value) for key, factory in self.factories.items(): value = factory() parsed_config.setdefault(key, value) return parsed_config PKcsēRŋöAŲŲdom_toml/__init__.py#!/usr/bin/env python3 # # __init__.py """ Dom's tools for Tom's Obvious, Minimal Language. """ # # Copyright ÂĐ 2021 Dominic Davis-Foster # # Based on https://github.com/uiri/toml # MIT Licensed # Copyright 2013-2019 William Pearson # Copyright 2015-2016 Julien Enselme # Copyright 2016 Google Inc. # Copyright 2017 Samuel Vasko # Copyright 2017 Nate Prewitt # Copyright 2017 Jack Evans # Copyright 2019 Filippo Broggini # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE # OR OTHER DEALINGS IN THE SOFTWARE. # # stdlib import warnings from typing import Any, Dict, Mapping, MutableMapping, Type, TypeVar, Union, overload # 3rd party import toml from domdf_python_tools.paths import PathPlus from domdf_python_tools.typing import PathLike # this package from dom_toml.encoder import TomlEncoder __author__: str = "Dominic Davis-Foster" __copyright__: str = "2021 Dominic Davis-Foster" __license__: str = "MIT License" __version__: str = "0.5.0" __email__: str = "dominic@davis-foster.co.uk" __all__ = ["TomlEncoder", "dumps", "loads", "dump", "load", "_M"] _M = TypeVar("_M", bound=MutableMapping[str, Any]) def dumps( data: Mapping[str, Any], encoder: Union[Type[toml.TomlEncoder], toml.TomlEncoder] = toml.TomlEncoder, ) -> str: r""" Convert ``data`` to a TOML string. :param data: :param encoder: The :class:`toml.TomlEncoder` to use for constructing the output string. :returns: A string containing the ``TOML`` corresponding to ``data``. .. versionchanged:: 0.5.0 The default value for ``encoder`` changed from :py:obj:`None` to :class:`toml.TomlEncoder` Explicitly passing ``encoder=None`` is deprecated and support will be removed in 1.0.0 """ if isinstance(encoder, type): encoder = encoder() elif encoder is None: warnings.warn( "Passing encoder=None to 'dom_toml.dumps' is deprecated since 0.5.0 and support will be removed in 1.0.0", DeprecationWarning, ) encoder = toml.TomlEncoder() return toml.dumps(data, encoder=encoder) def dump( data: Mapping[str, Any], filename: PathLike, encoder: Union[Type[toml.TomlEncoder], toml.TomlEncoder] = toml.TomlEncoder, ) -> str: r""" Writes out ``data`` as TOML to the given file. :param data: :param filename: The filename to write to. :param encoder: The :class:`toml.TomlEncoder` to use for constructing the output string. :returns: A string containing the ``TOML`` corresponding to ``data``. .. versionchanged:: 0.5.0 The default value for ``encoder`` changed from :py:obj:`None` to :class:`toml.TomlEncoder` Explicitly passing ``encoder=None`` is deprecated and support will be removed in 1.0.0 .. latex:clearpage:: """ filename = PathPlus(filename) as_toml = dumps(data, encoder=encoder) filename.write_clean(as_toml) return as_toml @overload def loads( s, dict_: Type[Dict[str, Any]] = ..., decoder: Union[Type[toml.TomlDecoder], toml.TomlDecoder] = toml.TomlDecoder, ) -> Dict[str, Any]: ... @overload def loads( s, dict_: Type[_M], decoder: Union[Type[toml.TomlDecoder], toml.TomlDecoder] = toml.TomlDecoder, ) -> _M: ... def loads( s, dict_: Type[_M] = dict, # type: ignore decoder: Union[Type[toml.TomlDecoder], toml.TomlDecoder] = toml.TomlDecoder, ) -> _M: r""" Parse the given string as TOML. :param s: :param dict\_: The class of the returned data. :param decoder: The :class:`toml.TomlEncoder` to use for constructing the output string. :returns: A mapping containing the ``TOML`` data. .. versionchanged:: 0.5.0 * The default value for ``decoder`` changed from :py:obj:`None` to :class:`toml.TomlDecoder` Explicitly passing ``decoder=``\ :py:obj:`None` is deprecated and support will be removed in 1.0.0 * Instead, pass a decoder class or, if you use the ``dict_`` option, an instance of the decoder class for ``dict_``. """ if decoder is None: warnings.warn( "Passing decoder=None to 'dom_toml.loads' is deprecated since 0.5.0 and support will be removed in 1.0.0", DeprecationWarning, ) decoder = toml.TomlDecoder(dict_) elif isinstance(decoder, type): if dict_ is dict: decoder = decoder() else: # TODO: deprecate this behaviour and the dict_ option in favour of passing an instance of the encoder. decoder = decoder(dict_) return toml.loads( # type: ignore s, decoder=decoder, ) @overload def load( filename: PathLike, dict_: Type[Dict[str, Any]] = ..., decoder: Union[Type[toml.TomlDecoder], toml.TomlDecoder] = toml.TomlDecoder, ) -> Dict[str, Any]: ... @overload def load( filename: PathLike, dict_: Type[_M], decoder: Union[Type[toml.TomlDecoder], toml.TomlDecoder] = toml.TomlDecoder, ) -> _M: ... def load( filename: PathLike, dict_: Type[_M] = dict, # type: ignore decoder: Union[Type[toml.TomlDecoder], toml.TomlDecoder] = toml.TomlDecoder, ) -> _M: r""" Parse TOML from the given file. :param filename: The filename to read from to. :param dict\_: The class of the returned data. :param decoder: The :class:`toml.TomlEncoder` to use for constructing the output string. :returns: A mapping containing the ``TOML`` data. .. versionchanged:: 0.5.0 * The default value for ``decoder`` changed from :py:obj:`None` to :class:`toml.TomlDecoder` Explicitly passing ``decoder=``\ :py:obj:`None` is deprecated and support will be removed in 1.0.0 * Instead, pass a decoder class or, if you use the ``dict_`` option, an instance of the decoder class for ``dict_``. .. latex:clearpage:: """ return loads( PathPlus(filename).read_text(), dict_=dict_, decoder=decoder, ) PKcsēRdom_toml/py.typedPKcsēRQØŪVîîdom_toml/decoder.py#!/usr/bin/env python3 # # decoder.py """ TOML decoders. .. versionadded:: 0.2.0 """ # # Copyright ÂĐ 2021 Dominic Davis-Foster # # Based on https://github.com/uiri/toml # MIT Licensed # Copyright 2013-2019 William Pearson # Copyright 2015-2016 Julien Enselme # Copyright 2016 Google Inc. # Copyright 2017 Samuel Vasko # Copyright 2017 Nate Prewitt # Copyright 2017 Jack Evans # Copyright 2019 Filippo Broggini # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE # OR OTHER DEALINGS IN THE SOFTWARE. # # 3rd party import toml __all__ = ["TomlPureDecoder"] class TomlPureDecoder(toml.decoder.TomlDecoder): """ TOML decoder which uses pure-Python dictionaries for inline tables. """ def get_empty_inline_table(self): # noqa: D102 return {} PKcsēR+ÚMj44dom_toml/encoder.py#!/usr/bin/env python3 # # encoder.py """ Dom's custom encoder for Tom's Obvious, Minimal Language. .. versionadded:: 0.2.0 .. autosummary-widths:: 6/16 10/16 """ # # Copyright ÂĐ 2021 Dominic Davis-Foster # # Based on https://github.com/uiri/toml # MIT Licensed # Copyright 2013-2019 William Pearson # Copyright 2015-2016 Julien Enselme # Copyright 2016 Google Inc. # Copyright 2017 Samuel Vasko # Copyright 2017 Nate Prewitt # Copyright 2017 Jack Evans # Copyright 2019 Filippo Broggini # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE # OR OTHER DEALINGS IN THE SOFTWARE. # # stdlib import re from typing import Mapping, Sequence, Tuple # 3rd party import toml from domdf_python_tools.stringlist import DelimitedList, StringList from toml.decoder import InlineTableDict __all__ = ["TomlEncoder"] _section_disallowed_re = re.compile(r'^[A-Za-z0-9_-]+$') class TomlEncoder(toml.TomlEncoder): """ Customised TOML encoder which wraps long lists onto multiple lines and adds a blank line before arrays of tables. .. versionchanged:: 0.2.0 Moved from ``__init__.py`` """ # noqa: D400 # The maximum width of the list **value**, after which it will be wrapped. max_width: int = 100 def dump_list(self, v) -> str: """ Serialize a list to TOML. :param v: :rtype: .. latex:clearpage:: """ single_line = super().dump_list(v) if len(single_line) <= self.max_width: return single_line retval = StringList(['[']) with retval.with_indent(" ", 1): for u in v: retval.append(f"{str(self.dump_value(u))},") retval.append(']') return str(retval) def dump_inline_table(self, section) -> str: """ Preserve an inline table in its compact syntax instead of expanding into sections. .. seealso:: https://github.com/toml-lang/toml/blob/master/toml.md#user-content-inline-table """ # See also: https://github.com/uiri/toml/pull/336/ if isinstance(section, Mapping): val_list: DelimitedList[str] = DelimitedList([]) for k, v in section.items(): val_list.append(f"{k} = {self.dump_inline_table(v).rstrip()}") return f"{{ {val_list:, } }}" else: return str(self.dump_value(section)) def dump_sections(self, o, sup) -> Tuple[str, Mapping]: """ Serialise a dictionary into TOML sections. :param o: :param sup: """ retstr = '' if sup != '' and sup[-1] != '.': sup += '.' arraystr = StringList() arraystr.indent_type = ' ' * 4 retdict = self._dict() # type: ignore for section in o: section = str(section) qsection = section if not _section_disallowed_re.match(section): qsection = _dump_str(section) if not isinstance(o[section], Mapping): arrayoftables = False if isinstance(o[section], Sequence): for a in o[section]: if isinstance(a, Mapping): arrayoftables = True if arrayoftables: for a in o[section]: arraytabstr = '\n' # if arraystr: arraystr.blankline(ensure_single=True) arraystr.append(f"[[{sup}{qsection}]]") s, d = self.dump_sections(a, sup + qsection) if s: if s[0] == '[': arraytabstr += s else: arraystr.append(s) while d: # pragma: no cover newd = self._dict() # type: ignore for dsec in d: s1, d1 = self.dump_sections(d[dsec], f"{sup}{qsection}.{dsec}") if s1: arraytabstr += f'[{sup}{qsection}.{dsec}]\n{s1}' for s1 in d1: newd[f"{dsec}.{s1}"] = d1[s1] d = newd arraystr.append(arraytabstr) else: if o[section] is not None: retstr += f"{qsection} = {self.dump_value(o[section])}\n" elif self.preserve and isinstance(o[section], InlineTableDict): retstr += f"{qsection} = {self.dump_inline_table(o[section])}" else: retdict[qsection] = o[section] retstr += str(arraystr) return retstr.lstrip(), retdict _SINGLE = "'" _DOUBLE = '"' _translation_table = { 8: "\\b", 9: "\\t", 10: "\\n", 12: "\\f", 13: "\\r", 92: "\\\\", } def _dump_str(v): v = str(v) v = v.translate(_translation_table) if _SINGLE in v and _DOUBLE not in v: quote_char = _DOUBLE elif _DOUBLE in v and _SINGLE not in v: quote_char = _SINGLE else: quote_char = _DOUBLE v = v.replace(_DOUBLE, f"\\{_DOUBLE}") return f"{quote_char}{v}{quote_char}" # Fix unicode characters on PyPy toml.encoder._dump_str = _dump_str # type: ignore PKcsēRą.Ĩ\\dom_toml-0.5.0.dist-info/RECORDdom_toml-0.5.0.dist-info/WHEEL,sha256=HVdHBMWW2H4KZrC08zrhHI_jORY8qNj2Xnqa5D-JhwA,84 dom_toml-0.5.0.dist-info/METADATA,sha256=9F11c9Jtr503Lete4c7pm3-G1Udd_KvWBcIBOZuDqwk,6476 dom_toml-0.5.0.dist-info/LICENSE,sha256=TXanB-tJYmHhByFsynyh-UGwh2VdTVVjbZeFz1utSWc,1064 dom_toml-0.5.0.dist-info/top_level.txt,sha256=DNCu-IOZopdCW0dmDxXOJs2zSd4TzTirZjfvy9D8zso,9 dom_toml-0.5.0.dist-info/entry_points.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 dom_toml/parser.py,sha256=-vsTHqc2T_1SvwIir8386hCiyhNJOsM8wGLKRgHR1ok,6810 dom_toml/__init__.py,sha256=eqXHi5-5K9eL5_dB6h7N7hFvdOg5uv9MoqyXmlsBn40,6617 dom_toml/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 dom_toml/decoder.py,sha256=Y05WNOPUKaoaVLk9azCcw1SoUJcOqTRzaHPdAUE-b8k,1774 dom_toml/encoder.py,sha256=USHwioIIeZvdSg5lOMzwcyqBzRLVeBJgdskqh3sl2kc,5428 dom_toml-0.5.0.dist-info/RECORD,, PKcsēR1uôTTĪdom_toml-0.5.0.dist-info/WHEELPKcsēR…&7LL!Īdom_toml-0.5.0.dist-info/METADATAPKcsēRÝlž}(( Īdom_toml-0.5.0.dist-info/LICENSEPKcsēRŠÕqĸ &Īdom_toml-0.5.0.dist-info/top_level.txtPKcsēR)ĪÎdom_toml-0.5.0.dist-info/entry_points.txtPKcsēR-ŒþššĪdom_toml/parser.pyPKcsēRŋöAŲŲĪß9dom_toml/__init__.pyPKcsēRĪęSdom_toml/py.typedPKcsēRQØŪVîîĪTdom_toml/decoder.pyPKcsēR+ÚMj44Ī8[dom_toml/encoder.pyPKcsēRą.Ĩ\\Īpdom_toml-0.5.0.dist-info/RECORDPK $6t