Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/zmq/sugar/frame.py: 44%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""0MQ Frame pure Python methods."""
3# Copyright (C) PyZMQ Developers
4# Distributed under the terms of the Modified BSD License.
6from __future__ import annotations
8from typing import Literal, overload
10import zmq
11from zmq.backend import Frame as FrameBase
13from .attrsettr import AttributeSetter
16def _draft(
17 v: tuple[int] | tuple[int, int] | tuple[int, int, int],
18 feature: str,
19) -> None:
20 zmq.error._check_version(v, feature)
21 if not zmq.DRAFT_API:
22 raise RuntimeError(
23 f"libzmq and pyzmq must be built with draft support for {feature}"
24 )
27class Frame(FrameBase, AttributeSetter):
28 """
29 A zmq message Frame class for non-copying send/recvs and access to message properties.
31 A ``zmq.Frame`` wraps an underlying ``zmq_msg_t``.
33 Message *properties* can be accessed by treating a Frame like a dictionary (``frame["User-Id"]``).
35 .. versionadded:: 14.4, libzmq 4
37 Frames created by ``recv(copy=False)`` can be used to access message properties and attributes,
38 such as the CURVE User-Id.
40 For example::
42 frames = socket.recv_multipart(copy=False)
43 user_id = frames[0]["User-Id"]
45 This class is used if you want to do non-copying send and recvs.
46 When you pass a chunk of bytes to this class, e.g. ``Frame(buf)``, the
47 ref-count of `buf` is increased by two: once because the Frame saves `buf` as
48 an instance attribute and another because a ZMQ message is created that
49 points to the buffer of `buf`. This second ref-count increase makes sure
50 that `buf` lives until all messages that use it have been sent.
51 Once 0MQ sends all the messages and it doesn't need the buffer of ``buf``,
52 0MQ will call ``Py_DECREF(s)``.
54 Parameters
55 ----------
57 data : object, optional
58 any object that provides the buffer interface will be used to
59 construct the 0MQ message data.
60 track : bool
61 whether a MessageTracker_ should be created to track this object.
62 Tracking a message has a cost at creation, because it creates a threadsafe
63 Event object.
64 copy : bool
65 default: use copy_threshold
66 Whether to create a copy of the data to pass to libzmq
67 or share the memory with libzmq.
68 If unspecified, copy_threshold is used.
69 copy_threshold: int
70 default: :const:`zmq.COPY_THRESHOLD`
71 If copy is unspecified, messages smaller than this many bytes
72 will be copied and messages larger than this will be shared with libzmq.
73 """
75 @overload
76 def __getitem__(self, key: int | Literal["routing_id"]) -> int: ...
77 @overload
78 def __getitem__(self, key: bytes | Literal["group"]) -> str: ...
79 @overload
80 def __getitem__(self, key: str) -> int | str: ...
81 def __getitem__(self, key: int | str | bytes) -> int | str:
82 # map Frame['User-Id'] to Frame.get('User-Id')
83 return self.get(key)
85 def __repr__(self) -> str:
86 """Return the str form of the message."""
87 nbytes = len(self)
88 msg_suffix = ""
89 if nbytes > 16:
90 msg_bytes = bytes(memoryview(self.buffer)[:12])
91 if nbytes >= 1e9:
92 unit = "GB"
93 n = nbytes // 1e9
94 elif nbytes >= 2**20:
95 unit = "MB"
96 n = nbytes // 1e6
97 elif nbytes >= 1e3:
98 unit = "kB"
99 n = nbytes // 1e3
100 else:
101 unit = "B"
102 n = nbytes
103 msg_suffix = f'...{n:.0f}{unit}'
104 else:
105 msg_bytes = self.bytes
107 _module = self.__class__.__module__
108 if _module == "zmq.sugar.frame":
109 _module = "zmq"
110 return f"<{_module}.{self.__class__.__name__}({msg_bytes!r}{msg_suffix})>"
112 @property
113 def group(self) -> str:
114 """The RADIO-DISH group of the message.
116 Requires libzmq >= 4.2 and pyzmq built with draft APIs enabled.
118 .. versionadded:: 17
119 """
120 _draft((4, 2), "RADIO-DISH")
121 return self.get('group')
123 @group.setter
124 def group(self, group: str | bytes) -> None:
125 _draft((4, 2), "RADIO-DISH")
126 self.set('group', group)
128 @property
129 def routing_id(self) -> int:
130 """The CLIENT-SERVER routing id of the message.
132 Requires libzmq >= 4.2 and pyzmq built with draft APIs enabled.
134 .. versionadded:: 17
135 """
136 _draft((4, 2), "CLIENT-SERVER")
137 return self.get('routing_id')
139 @routing_id.setter
140 def routing_id(self, routing_id: int) -> None:
141 _draft((4, 2), "CLIENT-SERVER")
142 self.set('routing_id', routing_id)
145# keep deprecated alias
146Message = Frame
148__all__ = ['Frame', 'Message']