diff options
author | Guido van Rossum <guido@python.org> | 2021-11-23 16:56:06 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-23 16:56:06 (GMT) |
commit | 5be98e57b3c3b36d1a1176b49c73b8822c6380e7 (patch) | |
tree | 4791beb2411c0112b19d8fa6b6e867bb33416299 /Tools/scripts/deepfreeze.py | |
parent | ae1965ccb4b1fad63fab40fe8805d1b8247668d3 (diff) | |
download | cpython-5be98e57b3c3b36d1a1176b49c73b8822c6380e7.zip cpython-5be98e57b3c3b36d1a1176b49c73b8822c6380e7.tar.gz cpython-5be98e57b3c3b36d1a1176b49c73b8822c6380e7.tar.bz2 |
bpo-45873: Get rid of bootstrap_python (#29717)
Instead we use $(PYTHON_FOR_REGEN) .../deepfreeze.py with the
frozen .h file as input, as we did for Windows in bpo-45850.
We also get rid of the code that generates the .h files
when make regen-frozen is run (i.e., .../make_frozen.py),
and the MANIFEST file.
Restore Python 3.8 and 3.9 as Windows host Python again
Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
Diffstat (limited to 'Tools/scripts/deepfreeze.py')
-rw-r--r-- | Tools/scripts/deepfreeze.py | 87 |
1 files changed, 46 insertions, 41 deletions
diff --git a/Tools/scripts/deepfreeze.py b/Tools/scripts/deepfreeze.py index b6d52b7..b840c4b 100644 --- a/Tools/scripts/deepfreeze.py +++ b/Tools/scripts/deepfreeze.py @@ -7,7 +7,7 @@ import os import re import time import types -import typing +from typing import Dict, FrozenSet, Tuple, TextIO import umarshal @@ -42,13 +42,14 @@ def get_localsplus(code: types.CodeType): def get_localsplus_counts(code: types.CodeType, - names: tuple[str, ...], - kinds: bytes) -> tuple[int, int, int, int]: + names: Tuple[str, ...], + kinds: bytes) -> Tuple[int, int, int, int]: nlocals = 0 nplaincellvars = 0 ncellvars = 0 nfreevars = 0 - for name, kind in zip(names, kinds, strict=True): + assert len(names) == len(kinds) + for name, kind in zip(names, kinds): if kind & CO_FAST_LOCAL: nlocals += 1 if kind & CO_FAST_CELL: @@ -71,7 +72,7 @@ PyUnicode_2BYTE_KIND = 2 PyUnicode_4BYTE_KIND = 4 -def analyze_character_width(s: str) -> tuple[int, bool]: +def analyze_character_width(s: str) -> Tuple[int, bool]: maxchar = ' ' for c in s: maxchar = max(maxchar, c) @@ -86,12 +87,17 @@ def analyze_character_width(s: str) -> tuple[int, bool]: return kind, ascii +def removesuffix(base: str, suffix: str) -> str: + if base.endswith(suffix): + return base[:len(base) - len(suffix)] + return base + class Printer: - def __init__(self, file: typing.TextIO): + def __init__(self, file: TextIO): self.level = 0 self.file = file - self.cache: dict[tuple[type, object], str] = {} + self.cache: Dict[Tuple[type, object], str] = {} self.hits, self.misses = 0, 0 self.patchups: list[str] = [] self.write('#include "Python.h"') @@ -231,7 +237,7 @@ class Printer: # otherwise MSVC doesn't like it. self.write(f".co_consts = {co_consts},") self.write(f".co_names = {co_names},") - self.write(f".co_firstinstr = (_Py_CODEUNIT *) {co_code.removesuffix('.ob_base.ob_base')}.ob_sval,") + self.write(f".co_firstinstr = (_Py_CODEUNIT *) {removesuffix(co_code, '.ob_base.ob_base')}.ob_sval,") self.write(f".co_exceptiontable = {co_exceptiontable},") self.field(code, "co_flags") self.write(".co_warmup = QUICKENING_INITIAL_WARMUP_VALUE,") @@ -259,7 +265,7 @@ class Printer: self.write(f".co_freevars = {co_freevars},") return f"& {name}.ob_base" - def generate_tuple(self, name: str, t: tuple[object, ...]) -> str: + def generate_tuple(self, name: str, t: Tuple[object, ...]) -> str: items = [self.generate(f"{name}_{i}", it) for i, it in enumerate(t)] self.write("static") with self.indent(): @@ -323,7 +329,7 @@ class Printer: self.write(f".cval = {{ {z.real}, {z.imag} }},") return f"&{name}.ob_base" - def generate_frozenset(self, name: str, fs: frozenset[object]) -> str: + def generate_frozenset(self, name: str, fs: FrozenSet[object]) -> str: ret = self.generate_tuple(name, tuple(sorted(fs))) self.write("// TODO: The above tuple should be a frozenset") return ret @@ -336,34 +342,33 @@ class Printer: # print(f"Cache hit {key!r:.40}: {self.cache[key]!r:.40}") return self.cache[key] self.misses += 1 - match obj: - case types.CodeType() | umarshal.Code() as code: - val = self.generate_code(name, code) - case tuple(t): - val = self.generate_tuple(name, t) - case str(s): - val = self.generate_unicode(name, s) - case bytes(b): - val = self.generate_bytes(name, b) - case True: - return "Py_True" - case False: - return "Py_False" - case int(i): - val = self.generate_int(name, i) - case float(x): - val = self.generate_float(name, x) - case complex() as z: - val = self.generate_complex(name, z) - case frozenset(fs): - val = self.generate_frozenset(name, fs) - case builtins.Ellipsis: - return "Py_Ellipsis" - case None: - return "Py_None" - case _: - raise TypeError( - f"Cannot generate code for {type(obj).__name__} object") + if isinstance(obj, types.CodeType) or isinstance(obj, umarshal.Code): + val = self.generate_code(name, obj) + elif isinstance(obj, tuple): + val = self.generate_tuple(name, obj) + elif isinstance(obj, str): + val = self.generate_unicode(name, obj) + elif isinstance(obj, bytes): + val = self.generate_bytes(name, obj) + elif obj is True: + return "Py_True" + elif obj is False: + return "Py_False" + elif isinstance(obj, int): + val = self.generate_int(name, obj) + elif isinstance(obj, float): + val = self.generate_float(name, obj) + elif isinstance(obj, complex): + val = self.generate_complex(name, obj) + elif isinstance(obj, frozenset): + val = self.generate_frozenset(name, obj) + elif obj is builtins.Ellipsis: + return "Py_Ellipsis" + elif obj is None: + return "Py_None" + else: + raise TypeError( + f"Cannot generate code for {type(obj).__name__} object") # print(f"Cache store {key!r:.40}: {val!r:.40}") self.cache[key] = val return val @@ -393,12 +398,12 @@ def decode_frozen_data(source: str) -> types.CodeType: del lines[0] while lines and re.match(FROZEN_DATA_LINE, lines[-1]) is None: del lines[-1] - values: tuple[int, ...] = ast.literal_eval("".join(lines)) + values: Tuple[int, ...] = ast.literal_eval("".join(lines).strip()) data = bytes(values) return umarshal.loads(data) -def generate(source: str, filename: str, modname: str, file: typing.TextIO) -> None: +def generate(source: str, filename: str, modname: str, file: TextIO) -> None: if is_frozen_header(source): code = decode_frozen_data(source) else: @@ -439,7 +444,7 @@ def main() -> None: verbose = args.verbose with open(args.file, encoding="utf-8") as f: source = f.read() - modname = args.module or os.path.basename(args.file).removesuffix(".py") + modname = args.module or removesuffix(os.path.basename(args.file), ".py") output = args.output or modname + ".c" with open(output, "w", encoding="utf-8") as file: with report_time("generate"): |