mirror of https://github.com/python/cpython
73 lines
1.7 KiB
Python
73 lines
1.7 KiB
Python
import dataclasses as dc
|
|
from typing import Literal, NoReturn, overload
|
|
|
|
|
|
@dc.dataclass
|
|
class ClinicError(Exception):
|
|
message: str
|
|
_: dc.KW_ONLY
|
|
lineno: int | None = None
|
|
filename: str | None = None
|
|
|
|
def __post_init__(self) -> None:
|
|
super().__init__(self.message)
|
|
|
|
def report(self, *, warn_only: bool = False) -> str:
|
|
msg = "Warning" if warn_only else "Error"
|
|
if self.filename is not None:
|
|
msg += f" in file {self.filename!r}"
|
|
if self.lineno is not None:
|
|
msg += f" on line {self.lineno}"
|
|
msg += ":\n"
|
|
msg += f"{self.message}\n"
|
|
return msg
|
|
|
|
|
|
class ParseError(ClinicError):
|
|
pass
|
|
|
|
|
|
@overload
|
|
def warn_or_fail(
|
|
*args: object,
|
|
fail: Literal[True],
|
|
filename: str | None = None,
|
|
line_number: int | None = None,
|
|
) -> NoReturn: ...
|
|
|
|
@overload
|
|
def warn_or_fail(
|
|
*args: object,
|
|
fail: Literal[False] = False,
|
|
filename: str | None = None,
|
|
line_number: int | None = None,
|
|
) -> None: ...
|
|
|
|
def warn_or_fail(
|
|
*args: object,
|
|
fail: bool = False,
|
|
filename: str | None = None,
|
|
line_number: int | None = None,
|
|
) -> None:
|
|
joined = " ".join([str(a) for a in args])
|
|
error = ClinicError(joined, filename=filename, lineno=line_number)
|
|
if fail:
|
|
raise error
|
|
else:
|
|
print(error.report(warn_only=True))
|
|
|
|
|
|
def warn(
|
|
*args: object,
|
|
filename: str | None = None,
|
|
line_number: int | None = None,
|
|
) -> None:
|
|
return warn_or_fail(*args, filename=filename, line_number=line_number, fail=False)
|
|
|
|
def fail(
|
|
*args: object,
|
|
filename: str | None = None,
|
|
line_number: int | None = None,
|
|
) -> NoReturn:
|
|
warn_or_fail(*args, filename=filename, line_number=line_number, fail=True)
|