Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,29 +48,29 @@ jobs:
fail-fast: true
matrix:
include:
- os: macos-13
python: "3.8"
- os: macos-15-intel
python: "3.9"
arch: x64

- os: macos-14
python: "3.13"
python: "3.14"
zmq: bundled
arch: arm64

- os: macos-13
- os: macos-15-intel
python: pypy-3.9
zmq: bundled
arch: x64

- os: ubuntu-22.04
python: "3.8"
python: "3.9"
zmq: bundled
tornado: none

- os: ubuntu-22.04
python: pypy-3.9
zmq: bundled

- os: ubuntu-22.04
python: pypy-3.8

- os: ubuntu-22.04
python: "3.9"

Expand Down Expand Up @@ -107,7 +107,7 @@ jobs:
free_threading: free_threading

- os: windows-2022
python: "3.8"
python: "3.9"
arch: x86

- os: windows-2022
Expand All @@ -129,7 +129,7 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python }}
architecture: ${{ matrix.arch || 'x64' }}
architecture: ${{ matrix.arch }}
# allows us to use '3.12' and get '-dev' while we wait
allow-prereleases: true
freethreaded: ${{ matrix.free_threading == 'free_threading' }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ jobs:
- name: setup python
uses: actions/setup-python@v6
with:
python-version: "3.11"
python-version: "3.13"
architecture: ${{ matrix.architecture }}

- name: locate windows-arm vcredist
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
This package contains Python bindings for [ZeroMQ](https://zeromq.org).
ØMQ is a lightweight and fast messaging implementation.

PyZMQ should work with any reasonable version of Python (≥ 3.8), as well as PyPy.
PyZMQ should work with any reasonable version of Python (≥ 3.9), as well as PyPy.
PyZMQ supports libzmq ≥ 3.2.2 (including 4.x).

For a summary of changes to pyzmq, see our
Expand Down
2 changes: 1 addition & 1 deletion docs/source/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ an overview of what the ØMQ API looks like in Python. For information on how to
ØMQ in general, see the many examples in the excellent [ØMQ Guide], all of which
have a version in Python.

PyZMQ works with Python 3 (≥ 3.8), as well as PyPy via CFFI.
PyZMQ works with Python 3 (≥ 3.9), as well as PyPy via CFFI.

Please don't hesitate to report pyzmq-specific issues to our [tracker] on GitHub.
General questions about ØMQ are better sent to the [ØMQ tracker] or [mailing list].
Expand Down
4 changes: 1 addition & 3 deletions examples/eventloop/echostream.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#!/usr/bin/env python
"""Adapted echo.py to put the send in the event loop using a ZMQStream."""

from typing import List

from tornado import ioloop

import zmq
Expand All @@ -16,7 +14,7 @@
stream = zmqstream.ZMQStream(s)


def echo(msg: List[bytes]):
def echo(msg: list[bytes]):
print(" ".join(map(repr, msg)))
stream.send_multipart(msg)

Expand Down
5 changes: 2 additions & 3 deletions examples/heartbeat/heartbeater.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"""

import time
from typing import Set

from tornado import ioloop

Expand All @@ -41,8 +40,8 @@ def __init__(
self.pongstream = pongstream
self.pongstream.on_recv(self.handle_pong)

self.hearts: Set = set()
self.responses: Set = set()
self.hearts: set = set()
self.responses: set = set()
self.lifetime = 0
self.tic = time.monotonic()

Expand Down
8 changes: 4 additions & 4 deletions examples/mongodb/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# -----------------------------------------------------------------------------

import json
from typing import Any, Dict, List
from typing import Any

import zmq

Expand All @@ -21,16 +21,16 @@ def __init__(self, connect_addr: str = 'tcp://127.0.0.1:5000'):
self._socket = self._context.socket(zmq.DEALER)
self._socket.connect(connect_addr)

def _send_recv_msg(self, msg: List[bytes]) -> str:
def _send_recv_msg(self, msg: list[bytes]) -> str:
self._socket.send_multipart(msg)
return self._socket.recv_multipart()[0].decode("utf8")

def get_doc(self, keys: Dict[str, Any]) -> Dict:
def get_doc(self, keys: dict[str, Any]) -> dict:
msg = [b'get', json.dumps(keys).encode("utf8")]
json_str = self._send_recv_msg(msg)
return json.loads(json_str)

def add_doc(self, doc: Dict) -> str:
def add_doc(self, doc: dict) -> str:
msg = [b'add', json.dumps(doc).encode("utf8")]
return self._send_recv_msg(msg)

Expand Down
6 changes: 3 additions & 3 deletions examples/mongodb/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# -----------------------------------------------------------------------------

import json
from typing import Any, Dict, Optional, Union
from typing import Any, Optional, Union

import pymongo
from bson import json_util
Expand Down Expand Up @@ -39,7 +39,7 @@ def __init__(
def _doc_to_json(self, doc: Any) -> str:
return json.dumps(doc, default=json_util.default)

def add_document(self, doc: Dict) -> Optional[str]:
def add_document(self, doc: dict) -> Optional[str]:
"""
Inserts a document (dictionary) into mongo database table
"""
Expand All @@ -50,7 +50,7 @@ def add_document(self, doc: Dict) -> Optional[str]:
return f'Error: {e}'
return None

def get_document_by_keys(self, keys: Dict[str, Any]) -> Union[Dict, str, None]:
def get_document_by_keys(self, keys: dict[str, Any]) -> Union[dict, str, None]:
"""
Attempts to return a single document from database table that matches
each key/value in keys dictionary.
Expand Down
4 changes: 2 additions & 2 deletions examples/monitoring/simple_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import threading
import time
from typing import Any, Dict
from typing import Any

import zmq
from zmq.utils.monitor import recv_monitor_message
Expand All @@ -35,7 +35,7 @@ def line() -> None:

def event_monitor(monitor: zmq.Socket) -> None:
while monitor.poll():
evt: Dict[str, Any] = {}
evt: dict[str, Any] = {}
mon_evt = recv_monitor_message(monitor)
evt.update(mon_evt)
evt['description'] = EVENT_MAP[evt['event']]
Expand Down
6 changes: 3 additions & 3 deletions examples/monitoring/zmq_monitor_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import asyncio
import threading
import time
from typing import Any, Dict
from typing import Any

import zmq
from zmq.utils.monitor import recv_monitor_message
Expand Down Expand Up @@ -70,7 +70,7 @@ async def run_loop() -> None:
while True:
try:
while monitor.poll():
evt: Dict[str, Any] = {}
evt: dict[str, Any] = {}
mon_evt = await recv_monitor_message(monitor)
evt.update(mon_evt)
evt['description'] = EVENT_MAP[evt['event']]
Expand Down Expand Up @@ -117,7 +117,7 @@ def event_monitor_thread(monitor: zmq.Socket) -> None:
while True:
try:
while monitor.poll():
evt: Dict[str, Any] = {}
evt: dict[str, Any] = {}
mon_evt = recv_monitor_message(monitor)
evt.update(mon_evt)
evt['description'] = EVENT_MAP[evt['event']]
Expand Down
8 changes: 5 additions & 3 deletions examples/recv_into/recv_into_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ def main() -> None:
B = np.empty_like(A)
assert not (A == B).all()

with zmq.Context() as ctx, ctx.socket(zmq.PUSH) as push, ctx.socket(
zmq.PULL
) as pull:
with (
zmq.Context() as ctx,
ctx.socket(zmq.PUSH) as push,
ctx.socket(zmq.PULL) as pull,
):
push.bind(url)
pull.connect(url)
print("sending:\n", A)
Expand Down
5 changes: 2 additions & 3 deletions examples/security/ioloop-ironhouse.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import logging
import os
import sys
from typing import List

from tornado import ioloop

Expand All @@ -27,7 +26,7 @@
from zmq.eventloop import zmqstream


def echo(server: zmqstream.ZMQStream, msg: List[bytes]) -> None:
def echo(server: zmqstream.ZMQStream, msg: list[bytes]) -> None:
logging.debug("server recvd %s", msg)
reply = msg + [b'World']
logging.debug("server sending %s", reply)
Expand All @@ -50,7 +49,7 @@ def setup_server(server_secret_file: str, endpoint: str = 'tcp://127.0.0.1:9000'
return server_stream


def client_msg_recvd(msg: List[bytes]):
def client_msg_recvd(msg: list[bytes]):
logging.debug("client recvd %s", msg)
logging.info("Ironhouse test OK")
# stop the loop when we get the reply
Expand Down
4 changes: 2 additions & 2 deletions examples/serialization/serialsocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import secrets
import zlib
from hashlib import sha256
from typing import Any, Dict, cast
from typing import Any, cast

import numpy

Expand Down Expand Up @@ -79,7 +79,7 @@ def recv_array(
self, flags: int = 0, copy: bool = True, track: bool = False
) -> numpy.ndarray:
"""recv a numpy array"""
md = cast(Dict[str, Any], self.recv_json(flags=flags))
md = cast(dict[str, Any], self.recv_json(flags=flags))
msg = self.recv(flags=flags, copy=copy, track=track)
A = numpy.frombuffer(msg, dtype=md['dtype']) # type: ignore
return A.reshape(md['shape'])
Expand Down
3 changes: 1 addition & 2 deletions examples/win32-interrupt/display.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
"""The display part of a simply two process chat app."""

# This file has been placed in the public domain.
from typing import List

import zmq
from zmq.utils.win32 import allow_interrupt


def main(addrs: List[str]):
def main(addrs: list[str]):
context = zmq.Context()
control = context.socket(zmq.PUB)
control.bind('inproc://control')
Expand Down
1 change: 0 additions & 1 deletion mypy.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
[mypy]
python_version = 3.8
allow_redefinition = True
#warn_unused_configs = True
#incremental = False
Expand Down
14 changes: 3 additions & 11 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,18 @@ authors = [
{ name = "Brian E. Granger" },
{ name = "Min Ragan-Kelley" },
]
license = { file = "LICENSE.md" }
requires-python = ">=3.8"
license = "BSD-3-Clause"
requires-python = ">=3.9"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"Intended Audience :: System Administrators",
"License :: OSI Approved :: BSD License",
"Operating System :: MacOS :: MacOS X",
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX",
"Topic :: System :: Networking",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
dependencies = ["cffi; implementation_name == 'pypy'"]
description = "Python bindings for 0MQ"
Expand All @@ -51,7 +43,7 @@ Tracker = "https://github.com/zeromq/pyzmq/issues"

[tool.scikit-build]
wheel.packages = ["zmq"]
wheel.license-files = ["licenses/LICENSE*"]
wheel.license-files = ["LICENSE*", "licenses/LICENSE*"]
# 3.15 is required by scikit-build-core
cmake.version = ">=3.15"
# only build/install the pyzmq component
Expand Down
8 changes: 5 additions & 3 deletions tests/test_asyncio.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,9 +410,11 @@ async def test_draft_asyncio():
pytest.skip("draft API")
if zmq.zmq_version_info() < (4, 3, 2):
pytest.skip("requires libzmq 4.3.2 for zmq_poller_fd")
with zmq.asyncio.Context() as ctx, ctx.socket(zmq.CLIENT) as client, ctx.socket(
zmq.SERVER
) as server:
with (
zmq.asyncio.Context() as ctx,
ctx.socket(zmq.CLIENT) as client,
ctx.socket(zmq.SERVER) as server,
):
server.bind_to_random_port("tcp://127.0.0.1")
client.connect(server.last_endpoint)
server.rcvtimeo = client.rcvtimeo = 100
Expand Down
7 changes: 4 additions & 3 deletions tests/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,10 @@ async def can_connect(self, server, client, timeout=1000):

@contextmanager
def push_pull(self):
with self.context.socket(zmq.PUSH) as server, self.context.socket(
zmq.PULL
) as client:
with (
self.context.socket(zmq.PUSH) as server,
self.context.socket(zmq.PULL) as client,
):
server.linger = 0
server.sndtimeo = 2000
client.linger = 0
Expand Down
8 changes: 5 additions & 3 deletions tests/test_zmqstream.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,11 @@ async def test_shadow_socket(context):


async def test_shadow_socket_close(context, caplog):
with warnings.catch_warnings(record=True) as records, context.socket(
zmq.PUSH
) as push, context.socket(zmq.PULL) as pull:
with (
warnings.catch_warnings(record=True) as records,
context.socket(zmq.PUSH) as push,
context.socket(zmq.PULL) as pull,
):
push.linger = pull.linger = 0
port = push.bind_to_random_port('tcp://127.0.0.1')
pull.connect(f'tcp://127.0.0.1:{port}')
Expand Down
3 changes: 1 addition & 2 deletions tests/zmq_test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import warnings
from functools import partial
from threading import Thread
from typing import List
from unittest import SkipTest, TestCase

from pytest import mark
Expand Down Expand Up @@ -69,7 +68,7 @@ class BaseZMQTestCase(TestCase):
green = False
teardown_timeout = 10
test_timeout_seconds = int(os.environ.get("ZMQ_TEST_TIMEOUT") or 60)
sockets: List[zmq.Socket]
sockets: list[zmq.Socket]

@property
def _should_test_timeout(self):
Expand Down
Loading
Loading