mirror of https://github.com/zeromq/pyzmq.git
128 lines
3.5 KiB
Python
128 lines
3.5 KiB
Python
"""
|
|
script for generating files that involve repetitive updates for zmq constants.
|
|
|
|
Run as `python3 buildutils/constants.py`
|
|
|
|
Run this after updating utils/constant_names
|
|
|
|
Currently generates the following files from templates:
|
|
|
|
- constant_enums.pxi
|
|
- constants.pyi
|
|
"""
|
|
|
|
# Copyright (C) PyZMQ Developers
|
|
# Distributed under the terms of the Modified BSD License.
|
|
|
|
import enum
|
|
import os
|
|
import sys
|
|
from subprocess import run
|
|
|
|
pjoin = os.path.join
|
|
|
|
buildutils = os.path.abspath(os.path.dirname(__file__))
|
|
root = pjoin(buildutils, os.path.pardir)
|
|
|
|
sys.path.insert(0, pjoin(root, 'zmq'))
|
|
import constants # noqa: E402
|
|
|
|
all_names = []
|
|
for name in constants.__all__:
|
|
item = getattr(constants, name)
|
|
if isinstance(item, enum.Enum):
|
|
all_names.append(name)
|
|
|
|
ifndef_t = """#ifndef {0}
|
|
#define {0} (_PYZMQ_UNDEFINED)
|
|
#endif
|
|
"""
|
|
|
|
|
|
def no_prefix(name):
|
|
"""does the given constant have a ZMQ_ prefix?"""
|
|
return name.startswith('E') and not name.startswith('EVENT')
|
|
|
|
|
|
def cython_enums():
|
|
"""generate `enum: ZMQ_CONST` block for constant_enums.pxi"""
|
|
lines = []
|
|
for name in all_names:
|
|
if no_prefix(name):
|
|
lines.append(f'enum: ZMQ_{name} "{name}"')
|
|
else:
|
|
lines.append(f'enum: ZMQ_{name}')
|
|
|
|
return dict(ZMQ_ENUMS='\n '.join(lines))
|
|
|
|
|
|
def ifndefs():
|
|
"""generate `#ifndef ZMQ_CONST` block for zmq_constants.h"""
|
|
lines = ['#define _PYZMQ_UNDEFINED (-9999)']
|
|
for name in all_names:
|
|
if not no_prefix(name):
|
|
name = f'ZMQ_{name}'
|
|
lines.append(ifndef_t.format(name))
|
|
return dict(ZMQ_IFNDEFS='\n'.join(lines))
|
|
|
|
|
|
def promoted_constants():
|
|
"""Generate CONST: int for mypy"""
|
|
original_lines = []
|
|
with open(constants.__file__) as f:
|
|
for line in f.readlines():
|
|
original_lines.append(line)
|
|
if "AUTOGENERATED_BELOW_HERE" in line:
|
|
original_file = "".join(original_lines)
|
|
break
|
|
else:
|
|
raise ValueError("Never encountered AUTOGENERATED_BELOW_HERE")
|
|
|
|
global_assignments = []
|
|
all_lines = ["__all__: list[str] = ["]
|
|
for cls_name in sorted(dir(constants)):
|
|
if cls_name.startswith("_"):
|
|
continue
|
|
cls = getattr(constants, cls_name)
|
|
if not isinstance(cls, type) or not issubclass(cls, enum.Enum):
|
|
continue
|
|
|
|
get_global_name = getattr(cls, "_global_name", lambda name: name)
|
|
all_lines.append(f' "{cls_name}",')
|
|
for key in cls.__members__:
|
|
global_name = get_global_name(key)
|
|
all_lines.append(f' "{global_name}",')
|
|
global_assignments.append(f"{global_name}: int = {cls_name}.{key}")
|
|
all_lines.append("]")
|
|
|
|
return dict(
|
|
original_file=original_file,
|
|
global_assignments="\n".join(global_assignments),
|
|
__all__="\n".join(all_lines),
|
|
)
|
|
|
|
|
|
def generate_file(fname, ns_func, dest_dir="."):
|
|
"""generate a constants file from its template"""
|
|
with open(pjoin(root, 'buildutils', 'templates', f'{fname}')) as f:
|
|
tpl = f.read()
|
|
out = tpl.format(**ns_func())
|
|
dest = pjoin(dest_dir, fname)
|
|
print(f"generating {dest} from template")
|
|
with open(dest, 'w') as f:
|
|
f.write(out)
|
|
if fname.endswith(".py"):
|
|
run(["ruff", "format", dest])
|
|
|
|
|
|
def render_constants():
|
|
"""render generated constant files from templates"""
|
|
generate_file(
|
|
"constant_enums.pxi", cython_enums, pjoin(root, 'zmq', 'backend', 'cython')
|
|
)
|
|
generate_file("constants.py", promoted_constants, pjoin(root, 'zmq'))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
render_constants()
|