|
import os |
|
import re |
|
|
|
from typing import TYPE_CHECKING |
|
|
|
from tomlkit.api import loads |
|
from tomlkit.toml_document import TOMLDocument |
|
|
|
|
|
if TYPE_CHECKING: |
|
from _typeshed import StrPath as _StrPath |
|
else: |
|
from typing import Union |
|
|
|
_StrPath = Union[str, os.PathLike] |
|
|
|
|
|
class TOMLFile: |
|
""" |
|
Represents a TOML file. |
|
|
|
:param path: path to the TOML file |
|
""" |
|
|
|
def __init__(self, path: _StrPath) -> None: |
|
self._path = path |
|
self._linesep = os.linesep |
|
|
|
def read(self) -> TOMLDocument: |
|
"""Read the file content as a :class:`tomlkit.toml_document.TOMLDocument`.""" |
|
with open(self._path, encoding="utf-8", newline="") as f: |
|
content = f.read() |
|
|
|
|
|
num_newline = content.count("\n") |
|
if num_newline > 0: |
|
num_win_eol = content.count("\r\n") |
|
if num_win_eol == num_newline: |
|
self._linesep = "\r\n" |
|
content = content.replace("\r\n", "\n") |
|
elif num_win_eol == 0: |
|
self._linesep = "\n" |
|
else: |
|
self._linesep = "mixed" |
|
|
|
return loads(content) |
|
|
|
def write(self, data: TOMLDocument) -> None: |
|
"""Write the TOMLDocument to the file.""" |
|
content = data.as_string() |
|
|
|
|
|
if self._linesep == "\n": |
|
content = content.replace("\r\n", "\n") |
|
elif self._linesep == "\r\n": |
|
content = re.sub(r"(?<!\r)\n", "\r\n", content) |
|
|
|
with open(self._path, "w", encoding="utf-8", newline="") as f: |
|
f.write(content) |
|
|