pre-commit-hooks/.venv/lib/python3.10/site-packages/iniconfig/_parse.py
2024-04-13 00:00:20 +00:00

83 lines
2.4 KiB
Python

from __future__ import annotations
from typing import NamedTuple
from .exceptions import ParseError
COMMENTCHARS = '#;'
class _ParsedLine(NamedTuple):
lineno: int
section: str | None
name: str | None
value: str | None
def parse_lines(path: str, line_iter: list[str]) -> list[_ParsedLine]:
result: list[_ParsedLine] = []
section = None
for lineno, line in enumerate(line_iter):
name, data = _parseline(path, line, lineno)
# new value
if name is not None and data is not None:
result.append(_ParsedLine(lineno, section, name, data))
# new section
elif name is not None and data is None:
if not name:
raise ParseError(path, lineno, 'empty section name')
section = name
result.append(_ParsedLine(lineno, section, None, None))
# continuation
elif name is None and data is not None:
if not result:
raise ParseError(path, lineno, 'unexpected value continuation')
last = result.pop()
if last.name is None:
raise ParseError(path, lineno, 'unexpected value continuation')
if last.value:
last = last._replace(value=f'{last.value}\n{data}')
else:
last = last._replace(value=data)
result.append(last)
return result
def _parseline(path: str, line: str, lineno: int) -> tuple[str | None, str | None]:
# blank lines
if iscommentline(line):
line = ''
else:
line = line.rstrip()
if not line:
return None, None
# section
if line[0] == '[':
realline = line
for c in COMMENTCHARS:
line = line.split(c)[0].rstrip()
if line[-1] == ']':
return line[1:-1], None
return None, realline.strip()
# value
elif not line[0].isspace():
try:
name, value = line.split('=', 1)
if ':' in name:
raise ValueError()
except ValueError:
try:
name, value = line.split(':', 1)
except ValueError:
raise ParseError(path, lineno, 'unexpected line: %r' % line)
return name.strip(), value.strip()
# continuation
else:
return None, line.strip()
def iscommentline(line: str) -> bool:
c = line.lstrip()[:1]
return c in COMMENTCHARS