Skip to content

Commit

Permalink
pythongh-113299: Create libclinic package
Browse files Browse the repository at this point in the history
* Create Tools/clinic/libclinic/ package.
* Move cpp.py to libclinic.
* Create libclinic.utils.
  • Loading branch information
vstinner committed Dec 20, 2023
1 parent 4afa7be commit b58b260
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 73 deletions.
79 changes: 6 additions & 73 deletions Tools/clinic/clinic.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import collections
import contextlib
import copy
import cpp
import dataclasses as dc
import enum
import functools
Expand Down Expand Up @@ -47,9 +46,13 @@
Protocol,
TypeVar,
cast,
overload,
)

from libclinic import cpp
from libclinic import utils
from libclinic.utils import ClinicError, warn, fail


# TODO:
#
# soon:
Expand Down Expand Up @@ -144,77 +147,6 @@ def text_accumulator() -> TextAccumulator:
return TextAccumulator(append, output)


@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


@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])
if clinic:
if filename is None:
filename = clinic.filename
if getattr(clinic, 'block_parser', None) and (line_number is None):
line_number = clinic.block_parser.line_number
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)


def quoted_for_c_string(s: str) -> str:
for old, new in (
('\\', '\\\\'), # must be first!
Expand Down Expand Up @@ -2681,6 +2613,7 @@ def __init__(

global clinic
clinic = self
utils.clinic = self

def add_include(self, name: str, reason: str,
*, condition: str | None = None) -> None:
Expand Down
Empty file.
File renamed without changes.
87 changes: 87 additions & 0 deletions Tools/clinic/libclinic/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
from __future__ import annotations

import dataclasses as dc
from typing import (
Literal,
NoReturn,
overload,
TYPE_CHECKING,
)

if TYPE_CHECKING:
from clinic import Clinic


# Clinic instance
clinic: 'Clinic' | None = None


@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


@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])
if clinic:
if filename is None:
filename = clinic.filename
if getattr(clinic, 'block_parser', None) and (line_number is None):
line_number = clinic.block_parser.line_number
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)

0 comments on commit b58b260

Please sign in to comment.