Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/iniconfig/_parse.py: 98%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

61 statements  

1from __future__ import annotations 

2from .exceptions import ParseError 

3 

4from typing import NamedTuple 

5 

6 

7COMMENTCHARS = "#;" 

8 

9 

10class _ParsedLine(NamedTuple): 

11 lineno: int 

12 section: str | None 

13 name: str | None 

14 value: str | None 

15 

16 

17def parse_lines(path: str, line_iter: list[str]) -> list[_ParsedLine]: 

18 result: list[_ParsedLine] = [] 

19 section = None 

20 for lineno, line in enumerate(line_iter): 

21 name, data = _parseline(path, line, lineno) 

22 # new value 

23 if name is not None and data is not None: 

24 result.append(_ParsedLine(lineno, section, name, data)) 

25 # new section 

26 elif name is not None and data is None: 

27 if not name: 

28 raise ParseError(path, lineno, "empty section name") 

29 section = name 

30 result.append(_ParsedLine(lineno, section, None, None)) 

31 # continuation 

32 elif name is None and data is not None: 

33 if not result: 

34 raise ParseError(path, lineno, "unexpected value continuation") 

35 last = result.pop() 

36 if last.name is None: 

37 raise ParseError(path, lineno, "unexpected value continuation") 

38 

39 if last.value: 

40 last = last._replace(value=f"{last.value}\n{data}") 

41 else: 

42 last = last._replace(value=data) 

43 result.append(last) 

44 return result 

45 

46 

47def _parseline(path: str, line: str, lineno: int) -> tuple[str | None, str | None]: 

48 # blank lines 

49 if iscommentline(line): 

50 line = "" 

51 else: 

52 line = line.rstrip() 

53 if not line: 

54 return None, None 

55 # section 

56 if line[0] == "[": 

57 realline = line 

58 for c in COMMENTCHARS: 

59 line = line.split(c)[0].rstrip() 

60 if line[-1] == "]": 

61 return line[1:-1], None 

62 return None, realline.strip() 

63 # value 

64 elif not line[0].isspace(): 

65 try: 

66 name, value = line.split("=", 1) 

67 if ":" in name: 

68 raise ValueError() 

69 except ValueError: 

70 try: 

71 name, value = line.split(":", 1) 

72 except ValueError: 

73 raise ParseError(path, lineno, "unexpected line: %r" % line) 

74 return name.strip(), value.strip() 

75 # continuation 

76 else: 

77 return None, line.strip() 

78 

79 

80def iscommentline(line: str) -> bool: 

81 c = line.lstrip()[:1] 

82 return c in COMMENTCHARS