Skip to content

Commit

Permalink
use enums for constants
Browse files Browse the repository at this point in the history
simple static declarations, rather than complex compile-time logic

no longer need separate tracking of socket option types either, can be tracked on SocketOption enum itself
  • Loading branch information
minrk committed Nov 23, 2021
1 parent d91200a commit 70d11b6
Show file tree
Hide file tree
Showing 41 changed files with 1,194 additions and 3,018 deletions.
2 changes: 1 addition & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[flake8]
exclude = .git,dist,docs,zmq/eventloop/minitornado
exclude = .git,dist,docs,zmq/eventloop/minitornado,buildutils/templates
ignore = E, F401, F403, F811, F841, W
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ jobs:
sudo ldconfig
popd
echo "ZMQ_PREFIX=/usr/local" >> "$GITHUB_ENV"
export ZMQ_DRAFT_API=1 >> "$GITHUB_ENV"
echo ZMQ_DRAFT_API=1 >> "$GITHUB_ENV"
- name: build pyzmq
run: |
Expand Down
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ repos:
rev: 3.9.2
hooks:
- id: flake8
exclude: ^buildutils/templates/
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.910
hooks:
Expand Down
25 changes: 0 additions & 25 deletions buildutils/build_cffi.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@
zmq_dir = os.path.join(os.path.dirname(here), 'zmq')
backend_dir = os.path.join(zmq_dir, 'backend', 'cffi')

# load constant names without zmq being importable
sys.path.insert(0, os.path.join(zmq_dir, "utils"))
from constant_names import all_names, no_prefix

sys.path = sys.path[1:]

ffi = cffi.FFI()


Expand Down Expand Up @@ -52,25 +46,6 @@ def load_compiler_config():
with open(os.path.join(backend_dir, '_cdefs.h')) as f:
ffi.cdef(f.read())


def _make_defines(names):
_names = []
for name in names:
define_line = "#define %s ..." % (name)
_names.append(define_line)

return "\n".join(_names)


c_constant_names = ['PYZMQ_DRAFT_API']
for name in all_names:
if no_prefix(name):
c_constant_names.append(name)
else:
c_constant_names.append("ZMQ_" + name)

ffi.cdef(_make_defines(c_constant_names))

with open(os.path.join(here, "_cffi.c")) as f:
_cffi_c = f.read()

Expand Down
80 changes: 50 additions & 30 deletions buildutils/constants.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
"""
script for generating files that involve repetitive updates for zmq constants.
Run as `python setup.py constants`
Run this after updating utils/constant_names
Currently generates the following files from templates:
- constant_enums.pxi
- constants.pxi
- zmq_constants.h
- constants.pyi
"""

# Copyright (C) PyZMQ Developers
# Distributed under the terms of the Modified BSD License.

import enum
import os
import sys

Expand All @@ -24,15 +25,26 @@
buildutils = os.path.abspath(os.path.dirname(__file__))
root = pjoin(buildutils, os.path.pardir)

sys.path.insert(0, pjoin(root, 'zmq', 'utils'))
from constant_names import all_names, no_prefix
sys.path.insert(0, pjoin(root, 'zmq'))
import constants

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 = []
Expand All @@ -55,27 +67,40 @@ def ifndefs():
return dict(ZMQ_IFNDEFS='\n'.join(lines))


def constants_pyi():
def promoted_constants():
"""Generate CONST: int for mypy"""
lines = []
for name in all_names:
lines.append(f"{name}: int")

return dict(constants="\n".join(lines))


def constants_pyx():
"""generate CONST = ZMQ_CONST and __all__ for constants.pxi"""
all_lines = []
assign_lines = []
for name in all_names:
if name == "NULL":
# avoid conflict with NULL in Cython
assign_lines.append("globals()['NULL'] = ZMQ_NULL")
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:
assign_lines.append('{0} = ZMQ_{0}'.format(name))
all_lines.append(' "{0}",'.format(name))
return dict(ASSIGNMENTS='\n'.join(assign_lines), ALL='\n'.join(all_lines))
raise ValueError("Never encountered AUTOGENERATED_BELOW_HERE")

global_assignments = []
all_lines = ["__all__: List[str] = ["]
for cls_name in 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="."):
Expand All @@ -94,12 +119,7 @@ def render_constants():
generate_file(
"constant_enums.pxi", cython_enums, pjoin(root, 'zmq', 'backend', 'cython')
)
generate_file(
"constants.pxi", constants_pyx, pjoin(root, 'zmq', 'backend', 'cython')
)
generate_file("constants.pyi", constants_pyi, pjoin(root, 'zmq', 'sugar'))
generate_file("constants.pyi", constants_pyi, pjoin(root, 'zmq', 'backend'))
generate_file("zmq_constants.h", ifndefs, pjoin(root, 'zmq', 'utils'))
generate_file("constants.py", promoted_constants, pjoin(root, 'zmq'))


if __name__ == '__main__':
Expand Down
4 changes: 4 additions & 0 deletions buildutils/templates/constant_enums.pxi
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
cdef extern from "zmq.h" nogil:
enum: PYZMQ_DRAFT_API
enum: ZMQ_VERSION
enum: ZMQ_VERSION_MAJOR
enum: ZMQ_VERSION_MINOR
enum: ZMQ_VERSION_PATCH
{ZMQ_ENUMS}
15 changes: 0 additions & 15 deletions buildutils/templates/constants.pxi

This file was deleted.

5 changes: 5 additions & 0 deletions buildutils/templates/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{original_file}

{global_assignments}

{__all__}
19 changes: 0 additions & 19 deletions buildutils/templates/constants.pyi

This file was deleted.

14 changes: 0 additions & 14 deletions buildutils/templates/zmq_constants.h

This file was deleted.

1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -1184,7 +1184,6 @@ def makename(path, ext):

submodules = {
'backend.cython': {
'constants': [libzmq, pxi('backend', 'cython', 'constants')],
'error': [libzmq, checkrc],
'_poll': [libzmq, socket, context, checkrc],
'utils': [libzmq, checkrc],
Expand Down
17 changes: 14 additions & 3 deletions zmq/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,11 @@ def _libs_on_path():
with _libs_on_path():
from zmq import backend

from zmq.backend import *
from . import constants # noqa
from .constants import * # noqa
from zmq.backend import * # noqa
from zmq import sugar
from zmq.sugar import *
from zmq.sugar import * # noqa


def get_includes():
Expand All @@ -129,4 +131,13 @@ def get_library_dirs():


COPY_THRESHOLD = 65536
__all__ = ['get_includes', 'COPY_THRESHOLD'] + sugar.__all__ + backend.__all__
DRAFT_API = backend.has("draft")
__all__ = (
[
'get_includes',
'COPY_THRESHOLD',
'DRAFT_API',
]
+ sugar.__all__
+ backend.__all__
)
2 changes: 2 additions & 0 deletions zmq/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ from . import sugar

from .error import *
from .sugar import *
from .constants import *

# mypy doesn't like overwriting symbols with * so be explicit
# about what comes from backend, not from sugar
Expand All @@ -25,6 +26,7 @@ from .backend import (
)

COPY_THRESHOLD: int
DRAFT_API: bool

def get_includes() -> List[str]: ...
def get_library_dirs() -> List[str]: ...
1 change: 0 additions & 1 deletion zmq/backend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import os
import platform
import sys

from .select import public_api, select_backend

Expand Down
4 changes: 1 addition & 3 deletions zmq/backend/cffi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
# Distributed under the terms of the Modified BSD License.

from zmq.backend.cffi import (
constants,
error,
message,
context,
Expand All @@ -28,10 +27,9 @@ def zmq_version_info():


__all__ = ["zmq_version_info"]
for submod in (constants, error, message, context, socket, _poll, devices, utils):
for submod in (error, message, context, socket, _poll, devices, utils):
__all__.extend(submod.__all__)

from .constants import *
from .error import *
from .message import *
from .context import *
Expand Down
24 changes: 0 additions & 24 deletions zmq/backend/cffi/constants.py

This file was deleted.

3 changes: 1 addition & 2 deletions zmq/backend/cffi/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@

from ._cffi import lib as C, ffi

from .constants import EINVAL, IO_THREADS, LINGER

from zmq.constants import EINVAL, IO_THREADS, LINGER
from zmq.error import ZMQError, InterruptedSystemCall, _check_rc


Expand Down
2 changes: 1 addition & 1 deletion zmq/backend/cffi/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
from threading import Event

from ._cffi import ffi, lib as C
from .constants import ETERM

import zmq
from zmq.constants import ETERM
from zmq.utils.strtypes import unicode
import zmq.error

Expand Down
Loading

0 comments on commit 70d11b6

Please sign in to comment.