/
githubmirror
/
os-python3.9
Обзор
Документация
Войти
/
githubmirror
/
os-python3.9
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
bullseye
Tools/peg_generator/pegen/testutil.py
133 строки
4 KB
Huw Jones
Imported Upstream version 3.9.2
21 мар 2022, 14:02
21 мар 2022, 14:02
0946962
Код
Авторство
О чём код?
import importlib.util import io import os import pathlib import sys import textwrap import tokenize import token from typing import Any, cast, Dict, IO, Type, Final from pegen.build import compile_c_extension from pegen.c_generator import CParserGenerator from pegen.grammar import Grammar from pegen.grammar_parser import GeneratedParser as GrammarParser from pegen.parser import Parser from pegen.python_generator import PythonParserGenerator from pegen.tokenizer import Tokenizer ALL_TOKENS = token.tok_name EXACT_TOKENS = token.EXACT_TOKEN_TYPES # type: ignore NON_EXACT_TOKENS = { name for index, name in token.tok_name.items() if index not in EXACT_TOKENS.values() } def generate_parser(grammar: Grammar) -> Type[Parser]: # Generate a parser. out = io.StringIO() genr = PythonParserGenerator(grammar, out) genr.generate("<string>") # Load the generated parser class. ns: Dict[str, Any] = {} exec(out.getvalue(), ns) return ns["GeneratedParser"] def run_parser(file: IO[bytes], parser_class: Type[Parser], *, verbose: bool = False) -> Any: # Run a parser on a file (stream). tokenizer = Tokenizer(tokenize.generate_tokens(file.readline)) # type: ignore # typeshed issue #3515 parser = parser_class(tokenizer, verbose=verbose) result = parser.start() if result is None: raise parser.make_syntax_error() return result def parse_string( source: str, parser_class: Type[Parser], *, dedent: bool = True, verbose: bool = False ) -> Any: # Run the parser on a string. if dedent: source = textwrap.dedent(source) file = io.StringIO(source) return run_parser(file, parser_class, verbose=verbose) # type: ignore # typeshed issue #3515 def make_parser(source: str) -> Type[Parser]: # Combine parse_string() and generate_parser(). grammar = parse_string(source, GrammarParser) return generate_parser(grammar) def import_file(full_name: str, path: str) -> Any: """Import a python module from a path""" spec = importlib.util.spec_from_file_location(full_name, path) mod = importlib.util.module_from_spec(spec) # We assume this is not None and has an exec_module() method. # See https://docs.python.org/3/reference/import.html?highlight=exec_module#loading loader = cast(Any, spec.loader) loader.exec_module(mod) return mod def generate_c_parser_source(grammar: Grammar) -> str: out = io.StringIO() genr = CParserGenerator(grammar, ALL_TOKENS, EXACT_TOKENS, NON_EXACT_TOKENS, out) genr.generate("<string>") return out.getvalue() def generate_parser_c_extension( grammar: Grammar, path: pathlib.PurePath, debug: bool = False ) -> Any: """Generate a parser c extension for the given grammar in the given path Returns a module object with a parse_string() method. TODO: express that using a Protocol. """ # Make sure that the working directory is empty: reusing non-empty temporary # directories when generating extensions can lead to segmentation faults. # Check issue #95 (https://github.com/gvanrossum/pegen/issues/95) for more # context. assert not os.listdir(path) source = path / "parse.c" with open(source, "w", encoding="utf-8") as file: genr = CParserGenerator( grammar, ALL_TOKENS, EXACT_TOKENS, NON_EXACT_TOKENS, file, debug=debug ) genr.generate("parse.c") compile_c_extension(str(source), build_dir=str(path)) def print_memstats() -> bool: MiB: Final = 2 ** 20 try: import psutil # type: ignore except ImportError: return False print("Memory stats:") process = psutil.Process() meminfo = process.memory_info() res = {} res["rss"] = meminfo.rss / MiB res["vms"] = meminfo.vms / MiB if sys.platform == "win32": res["maxrss"] = meminfo.peak_wset / MiB else: # See https://stackoverflow.com/questions/938733/total-memory-used-by-python-process import resource # Since it doesn't exist on Windows. rusage = resource.getrusage(resource.RUSAGE_SELF) if sys.platform == "darwin": factor = 1 else: factor = 1024 # Linux res["maxrss"] = rusage.ru_maxrss * factor / MiB for key, value in res.items(): print(f" {key:12.12s}: {value:10.0f} MiB") return True