mirror of https://github.com/python/cpython
54 lines
1.5 KiB
Python
54 lines
1.5 KiB
Python
|
from __future__ import annotations
|
||
|
import contextlib
|
||
|
import functools
|
||
|
import io
|
||
|
from types import NoneType
|
||
|
from typing import Any, Protocol, TYPE_CHECKING
|
||
|
|
||
|
from libclinic import unspecified
|
||
|
from libclinic.block_parser import Block
|
||
|
from libclinic.converter import CConverter, converters
|
||
|
from libclinic.converters import buffer, robuffer, rwbuffer
|
||
|
from libclinic.return_converters import CReturnConverter, return_converters
|
||
|
if TYPE_CHECKING:
|
||
|
from libclinic.app import Clinic
|
||
|
|
||
|
|
||
|
class Parser(Protocol):
|
||
|
def __init__(self, clinic: Clinic) -> None: ...
|
||
|
def parse(self, block: Block) -> None: ...
|
||
|
|
||
|
|
||
|
@functools.cache
|
||
|
def _create_parser_base_namespace() -> dict[str, Any]:
|
||
|
ns = dict(
|
||
|
CConverter=CConverter,
|
||
|
CReturnConverter=CReturnConverter,
|
||
|
buffer=buffer,
|
||
|
robuffer=robuffer,
|
||
|
rwbuffer=rwbuffer,
|
||
|
unspecified=unspecified,
|
||
|
NoneType=NoneType,
|
||
|
)
|
||
|
for name, converter in converters.items():
|
||
|
ns[f'{name}_converter'] = converter
|
||
|
for name, return_converter in return_converters.items():
|
||
|
ns[f'{name}_return_converter'] = return_converter
|
||
|
return ns
|
||
|
|
||
|
|
||
|
def create_parser_namespace() -> dict[str, Any]:
|
||
|
base_namespace = _create_parser_base_namespace()
|
||
|
return base_namespace.copy()
|
||
|
|
||
|
|
||
|
class PythonParser:
|
||
|
def __init__(self, clinic: Clinic) -> None:
|
||
|
pass
|
||
|
|
||
|
def parse(self, block: Block) -> None:
|
||
|
namespace = create_parser_namespace()
|
||
|
with contextlib.redirect_stdout(io.StringIO()) as s:
|
||
|
exec(block.input, namespace)
|
||
|
block.output = s.getvalue()
|