error.py 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. from __future__ import annotations
  2. import warnings
  3. # import textwrap
  4. if False: # MYPY
  5. from typing import Any, Dict, Optional, List, Text # NOQA
  6. __all__ = [
  7. 'FileMark',
  8. 'StringMark',
  9. 'CommentMark',
  10. 'YAMLError',
  11. 'MarkedYAMLError',
  12. 'ReusedAnchorWarning',
  13. 'UnsafeLoaderWarning',
  14. 'MarkedYAMLWarning',
  15. 'MarkedYAMLFutureWarning',
  16. ]
  17. class StreamMark:
  18. __slots__ = 'name', 'index', 'line', 'column'
  19. def __init__(self, name: Any, index: int, line: int, column: int) -> None:
  20. self.name = name
  21. self.index = index
  22. self.line = line
  23. self.column = column
  24. def __str__(self) -> Any:
  25. where = f' in "{self.name!s}", line {self.line + 1:d}, column {self.column + 1:d}'
  26. return where
  27. def __eq__(self, other: Any) -> bool:
  28. if self.line != other.line or self.column != other.column:
  29. return False
  30. if self.name != other.name or self.index != other.index:
  31. return False
  32. return True
  33. def __ne__(self, other: Any) -> bool:
  34. return not self.__eq__(other)
  35. class FileMark(StreamMark):
  36. __slots__ = ()
  37. class StringMark(StreamMark):
  38. __slots__ = 'name', 'index', 'line', 'column', 'buffer', 'pointer'
  39. def __init__(
  40. self, name: Any, index: int, line: int, column: int, buffer: Any, pointer: Any,
  41. ) -> None:
  42. StreamMark.__init__(self, name, index, line, column)
  43. self.buffer = buffer
  44. self.pointer = pointer
  45. def get_snippet(self, indent: int = 4, max_length: int = 75) -> Any:
  46. if self.buffer is None: # always False
  47. return None
  48. head = ""
  49. start = self.pointer
  50. while start > 0 and self.buffer[start - 1] not in '\0\r\n\x85\u2028\u2029':
  51. start -= 1
  52. if self.pointer - start > max_length / 2 - 1:
  53. head = ' ... '
  54. start += 5
  55. break
  56. tail = ""
  57. end = self.pointer
  58. while end < len(self.buffer) and self.buffer[end] not in '\0\r\n\x85\u2028\u2029':
  59. end += 1
  60. if end - self.pointer > max_length / 2 - 1:
  61. tail = ' ... '
  62. end -= 5
  63. break
  64. snippet = self.buffer[start:end]
  65. caret = '^'
  66. caret = f'^ (line: {self.line + 1})'
  67. return (
  68. ' ' * indent
  69. + head
  70. + snippet
  71. + tail
  72. + '\n'
  73. + ' ' * (indent + self.pointer - start + len(head))
  74. + caret
  75. )
  76. def __str__(self) -> Any:
  77. snippet = self.get_snippet()
  78. where = f' in "{self.name!s}", line {self.line + 1:d}, column {self.column + 1:d}'
  79. if snippet is not None:
  80. where += ':\n' + snippet
  81. return where
  82. def __repr__(self) -> Any:
  83. snippet = self.get_snippet()
  84. where = f' in "{self.name!s}", line {self.line + 1:d}, column {self.column + 1:d}'
  85. if snippet is not None:
  86. where += ':\n' + snippet
  87. return where
  88. class CommentMark:
  89. __slots__ = ('column',)
  90. def __init__(self, column: Any) -> None:
  91. self.column = column
  92. class YAMLError(Exception):
  93. pass
  94. class MarkedYAMLError(YAMLError):
  95. def __init__( # NOQA
  96. self,
  97. context: Any = None,
  98. context_mark: Any = None,
  99. problem: Any = None,
  100. problem_mark: Any = None,
  101. note: Any = None,
  102. warn: Any = None,
  103. ) -> None:
  104. self.context = context
  105. self.context_mark = context_mark
  106. self.problem = problem
  107. self.problem_mark = problem_mark
  108. self.note = note
  109. # warn is ignored
  110. def __str__(self) -> Any:
  111. lines: list[str] = []
  112. if self.context is not None:
  113. lines.append(self.context)
  114. if self.context_mark is not None and (
  115. self.problem is None
  116. or self.problem_mark is None
  117. or self.context_mark.name != self.problem_mark.name
  118. or self.context_mark.line != self.problem_mark.line
  119. or self.context_mark.column != self.problem_mark.column
  120. ):
  121. lines.append(str(self.context_mark))
  122. if self.problem is not None:
  123. lines.append(self.problem)
  124. if self.problem_mark is not None:
  125. lines.append(str(self.problem_mark))
  126. # if self.note is not None and self.note:
  127. # note = textwrap.dedent(self.note)
  128. # lines.append(note)
  129. self.check_append(lines, self.note)
  130. return '\n'.join(lines)
  131. def check_append(self, lines: list[str], val: Optional[str]) -> None:
  132. if val is None or not val:
  133. return
  134. import textwrap
  135. note = textwrap.dedent(val)
  136. lines.append(note)
  137. class YAMLStreamError(Exception):
  138. pass
  139. class YAMLWarning(Warning):
  140. pass
  141. class MarkedYAMLWarning(YAMLWarning):
  142. def __init__( # NOQA
  143. self,
  144. context: Any = None,
  145. context_mark: Any = None,
  146. problem: Any = None,
  147. problem_mark: Any = None,
  148. note: Any = None,
  149. warn: Any = None,
  150. ) -> None:
  151. self.context = context
  152. self.context_mark = context_mark
  153. self.problem = problem
  154. self.problem_mark = problem_mark
  155. self.note = note
  156. self.warn = warn
  157. def __str__(self) -> Any:
  158. lines: List[str] = []
  159. if self.context is not None:
  160. lines.append(self.context)
  161. if self.context_mark is not None and (
  162. self.problem is None
  163. or self.problem_mark is None
  164. or self.context_mark.name != self.problem_mark.name
  165. or self.context_mark.line != self.problem_mark.line
  166. or self.context_mark.column != self.problem_mark.column
  167. ):
  168. lines.append(str(self.context_mark))
  169. if self.problem is not None:
  170. lines.append(self.problem)
  171. if self.problem_mark is not None:
  172. lines.append(str(self.problem_mark))
  173. # if self.note is not None and self.note:
  174. # note = textwrap.dedent(self.note)
  175. # lines.append(note)
  176. self.check_append(lines, self.note)
  177. # if self.warn is not None and self.warn:
  178. # warn = textwrap.dedent(self.warn)
  179. # lines.append(warn)
  180. self.check_append(lines, self.warn)
  181. return '\n'.join(lines)
  182. def check_append(self, lines: list[str], val: Optional[str]) -> None:
  183. if val is None or not val:
  184. return
  185. import textwrap
  186. note = textwrap.dedent(val)
  187. lines.append(note)
  188. class ReusedAnchorWarning(YAMLWarning):
  189. pass
  190. class UnsafeLoaderWarning(YAMLWarning):
  191. text = """
  192. The default 'Loader' for 'load(stream)' without further arguments can be unsafe.
  193. Use 'load(stream, Loader=ruamel.yaml.Loader)' explicitly if that is OK.
  194. Alternatively include the following in your code:
  195. import warnings
  196. warnings.simplefilter('ignore', ruamel.yaml.error.UnsafeLoaderWarning)
  197. In most other cases you should consider using 'safe_load(stream)'"""
  198. pass
  199. warnings.simplefilter('once', UnsafeLoaderWarning)
  200. class MantissaNoDotYAML1_1Warning(YAMLWarning):
  201. def __init__(self, node: Any, flt_str: Any) -> None: # NOQA
  202. self.node = node
  203. self.flt = flt_str
  204. def __str__(self) -> Any:
  205. line = self.node.start_mark.line
  206. col = self.node.start_mark.column
  207. return f"""
  208. In YAML 1.1 floating point values should have a dot ('.') in their mantissa.
  209. See the Floating-Point Language-Independent Type for YAML™ Version 1.1 specification
  210. ( http://yaml.org/type/float.html ). This dot is not required for JSON nor for YAML 1.2
  211. Correct your float: "{self.flt}" on line: {line}, column: {col}
  212. or alternatively include the following in your code:
  213. import warnings
  214. warnings.simplefilter('ignore', ruamel.yaml.error.MantissaNoDotYAML1_1Warning)
  215. """
  216. warnings.simplefilter('once', MantissaNoDotYAML1_1Warning)
  217. class YAMLFutureWarning(Warning):
  218. pass
  219. class MarkedYAMLFutureWarning(YAMLFutureWarning):
  220. def __init__( # NOQA
  221. self,
  222. context: Any = None,
  223. context_mark: Any = None,
  224. problem: Any = None,
  225. problem_mark: Any = None,
  226. note: Any = None,
  227. warn: Any = None,
  228. ) -> None:
  229. self.context = context
  230. self.context_mark = context_mark
  231. self.problem = problem
  232. self.problem_mark = problem_mark
  233. self.note = note
  234. self.warn = warn
  235. def __str__(self) -> Any:
  236. lines: List[str] = []
  237. if self.context is not None:
  238. lines.append(self.context)
  239. if self.context_mark is not None and (
  240. self.problem is None
  241. or self.problem_mark is None
  242. or self.context_mark.name != self.problem_mark.name
  243. or self.context_mark.line != self.problem_mark.line
  244. or self.context_mark.column != self.problem_mark.column
  245. ):
  246. lines.append(str(self.context_mark))
  247. if self.problem is not None:
  248. lines.append(self.problem)
  249. if self.problem_mark is not None:
  250. lines.append(str(self.problem_mark))
  251. # if self.note is not None and self.note:
  252. # note = textwrap.dedent(self.note)
  253. # lines.append(note)
  254. self.check_append(lines, self.note)
  255. # if self.warn is not None and self.warn:
  256. # warn = textwrap.dedent(self.warn)
  257. # lines.append(warn)
  258. self.check_append(lines, self.warn)
  259. return '\n'.join(lines)
  260. def check_append(self, lines: list[str], val: Optional[str]) -> None:
  261. if val is None or not val:
  262. return
  263. import textwrap
  264. note = textwrap.dedent(val)
  265. lines.append(note)