~ubuntu-branches/ubuntu/wily/pyzmq/wily

« back to all changes in this revision

Viewing changes to zmq/core/pysocket.py

  • Committer: Package Import Robot
  • Author(s): Julian Taylor
  • Date: 2013-02-24 19:23:15 UTC
  • mfrom: (1.2.1) (9 sid)
  • mto: This revision was merged to the branch mainline in revision 10.
  • Revision ID: package-import@ubuntu.com-20130224192315-qhmwp3m3ymk8r60d
Tags: 2.2.0.1-1
* New upstream release
* relicense debian packaging to LGPL-3
* update watch file to use github directly
  thanks to Bart Martens for the file
* add autopkgtests
* drop obsolete DM-Upload-Allowed
* bump standard to 3.9.4, no changes required

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""0MQ Socket pure Python methods."""
 
2
 
 
3
#
 
4
#    Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
 
5
#
 
6
#    This file is part of pyzmq.
 
7
#
 
8
#    pyzmq is free software; you can redistribute it and/or modify it under
 
9
#    the terms of the Lesser GNU General Public License as published by
 
10
#    the Free Software Foundation; either version 3 of the License, or
 
11
#    (at your option) any later version.
 
12
#
 
13
#    pyzmq is distributed in the hope that it will be useful,
 
14
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
#    Lesser GNU General Public License for more details.
 
17
#
 
18
#    You should have received a copy of the Lesser GNU General Public License
 
19
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
20
#
 
21
 
 
22
#-----------------------------------------------------------------------------
 
23
# Python Imports
 
24
#-----------------------------------------------------------------------------
 
25
 
 
26
import random
 
27
import codecs
 
28
 
 
29
import zmq
 
30
from zmq.core import constants
 
31
from zmq.core.constants import *
 
32
from zmq.core.error import ZMQError, ZMQBindError
 
33
from zmq.utils import jsonapi
 
34
from zmq.utils.strtypes import bytes,unicode,basestring
 
35
 
 
36
try:
 
37
    import cPickle
 
38
    pickle = cPickle
 
39
except:
 
40
    cPickle = None
 
41
    import pickle
 
42
 
 
43
#-----------------------------------------------------------------------------
 
44
# Code
 
45
#-----------------------------------------------------------------------------
 
46
 
 
47
def setsockopt_string(self, option, optval, encoding='utf-8'):
 
48
    """s.setsockopt_string(option, optval, encoding='utf-8')
 
49
 
 
50
    Set socket options with a unicode object it is simply a wrapper
 
51
    for setsockopt to protect from encoding ambiguity.
 
52
 
 
53
    See the 0MQ documentation for details on specific options.
 
54
 
 
55
    Parameters
 
56
    ----------
 
57
    option : int
 
58
        The name of the option to set. Can be any of: SUBSCRIBE, 
 
59
        UNSUBSCRIBE, IDENTITY
 
60
    optval : unicode string (unicode on py2, str on py3)
 
61
        The value of the option to set.
 
62
    encoding : str
 
63
        The encoding to be used, default is utf8
 
64
    """
 
65
    if not isinstance(optval, unicode):
 
66
        raise TypeError("unicode strings only")
 
67
    return self.setsockopt(option, optval.encode(encoding))
 
68
 
 
69
def setsockopt_string(self, option, optval, encoding='utf-8'):
 
70
    """s.setsockopt_string(option, optval, encoding='utf-8')
 
71
 
 
72
    Set socket options with a unicode object it is simply a wrapper
 
73
    for setsockopt to protect from encoding ambiguity.
 
74
 
 
75
    See the 0MQ documentation for details on specific options.
 
76
 
 
77
    Parameters
 
78
    ----------
 
79
    option : int
 
80
        The name of the option to set. Can be any of: SUBSCRIBE, 
 
81
        UNSUBSCRIBE, IDENTITY
 
82
    optval : unicode string (unicode on py2, str on py3)
 
83
        The value of the option to set.
 
84
    encoding : str
 
85
        The encoding to be used, default is utf8
 
86
    """
 
87
    if not isinstance(optval, unicode):
 
88
        raise TypeError("unicode strings only")
 
89
    return self.setsockopt(option, optval.encode(encoding))
 
90
 
 
91
def getsockopt_string(self, option, encoding='utf-8'):
 
92
    """s.getsockopt_string(option, encoding='utf-8')
 
93
 
 
94
    Get the value of a socket option.
 
95
 
 
96
    See the 0MQ documentation for details on specific options.
 
97
 
 
98
    Parameters
 
99
    ----------
 
100
    option : int
 
101
        The option to retrieve. Currently, IDENTITY is the only
 
102
        gettable option that can return a string.
 
103
 
 
104
    Returns
 
105
    -------
 
106
    optval : unicode string (unicode on py2, str on py3)
 
107
        The value of the option as a unicode string.
 
108
    """
 
109
    
 
110
    if option not in constants.bytes_sockopts:
 
111
        raise TypeError("option %i will not return a string to be decoded"%option)
 
112
    return self.getsockopt(option).decode(encoding)
 
113
 
 
114
def bind_to_random_port(self, addr, min_port=49152, max_port=65536, max_tries=100):
 
115
    """s.bind_to_random_port(addr, min_port=49152, max_port=65536, max_tries=100)
 
116
 
 
117
    Bind this socket to a random port in a range.
 
118
 
 
119
    Parameters
 
120
    ----------
 
121
    addr : str
 
122
        The address string without the port to pass to ``Socket.bind()``.
 
123
    min_port : int, optional
 
124
        The minimum port in the range of ports to try (inclusive).
 
125
    max_port : int, optional
 
126
        The maximum port in the range of ports to try (exclusive).
 
127
    max_tries : int, optional
 
128
        The maximum number of bind attempts to make.
 
129
 
 
130
    Returns
 
131
    -------
 
132
    port : int
 
133
        The port the socket was bound to.
 
134
    
 
135
    Raises
 
136
    ------
 
137
    ZMQBindError
 
138
        if `max_tries` reached before successful bind
 
139
    """
 
140
    for i in range(max_tries):
 
141
        try:
 
142
            port = random.randrange(min_port, max_port)
 
143
            self.bind('%s:%s' % (addr, port))
 
144
        except ZMQError:
 
145
            pass
 
146
        else:
 
147
            return port
 
148
    raise ZMQBindError("Could not bind socket to random port.")
 
149
 
 
150
#-------------------------------------------------------------------------
 
151
# Sending and receiving messages
 
152
#-------------------------------------------------------------------------
 
153
 
 
154
def send_multipart(self, msg_parts, flags=0, copy=True, track=False):
 
155
    """s.send_multipart(msg_parts, flags=0, copy=True, track=False)
 
156
 
 
157
    Send a sequence of buffers as a multipart message.
 
158
 
 
159
    Parameters
 
160
    ----------
 
161
    msg_parts : iterable
 
162
        A sequence of objects to send as a multipart message. Each element
 
163
        can be any sendable object (Frame, bytes, buffer-providers)
 
164
    flags : int, optional
 
165
        SNDMORE is handled automatically for frames before the last.
 
166
    copy : bool, optional
 
167
        Should the frame(s) be sent in a copying or non-copying manner.
 
168
    track : bool, optional
 
169
        Should the frame(s) be tracked for notification that ZMQ has
 
170
        finished with it (ignored if copy=True).
 
171
    
 
172
    Returns
 
173
    -------
 
174
    None : if copy or not track
 
175
    MessageTracker : if track and not copy
 
176
        a MessageTracker object, whose `pending` property will
 
177
        be True until the last send is completed.
 
178
    """
 
179
    for msg in msg_parts[:-1]:
 
180
        self.send(msg, SNDMORE|flags, copy=copy, track=track)
 
181
    # Send the last part without the extra SNDMORE flag.
 
182
    return self.send(msg_parts[-1], flags, copy=copy, track=track)
 
183
 
 
184
def recv_multipart(self, flags=0, copy=True, track=False):
 
185
    """s.recv_multipart(flags=0, copy=True, track=False)
 
186
 
 
187
    Receive a multipart message as a list of bytes or Frame objects.
 
188
 
 
189
    Parameters
 
190
    ----------
 
191
    flags : int, optional
 
192
        Any supported flag: NOBLOCK. If NOBLOCK is set, this method
 
193
        will raise a ZMQError with EAGAIN if a message is not ready.
 
194
        If NOBLOCK is not set, then this method will block until a
 
195
        message arrives.
 
196
    copy : bool, optional
 
197
        Should the message frame(s) be received in a copying or non-copying manner?
 
198
        If False a Frame object is returned for each part, if True a copy of
 
199
        the bytes is made for each frame.
 
200
    track : bool, optional
 
201
        Should the message frame(s) be tracked for notification that ZMQ has
 
202
        finished with it? (ignored if copy=True)
 
203
    Returns
 
204
    -------
 
205
    msg_parts : list
 
206
        A list of frames in the multipart message; either Frames or bytes,
 
207
        depending on `copy`.
 
208
    
 
209
    """
 
210
    parts = [self.recv(flags, copy=copy, track=track)]
 
211
    # have first part already, only loop while more to receive
 
212
    while self.getsockopt(zmq.RCVMORE):
 
213
        part = self.recv(flags, copy=copy, track=track)
 
214
        parts.append(part)
 
215
    
 
216
    return parts
 
217
 
 
218
def send_string(self, u, flags=0, copy=False, encoding='utf-8'):
 
219
    """s.send_string(u, flags=0, copy=False, encoding='utf-8')
 
220
 
 
221
    Send a Python unicode string as a message with an encoding.
 
222
    
 
223
    0MQ communicates with raw bytes, so you must encode/decode
 
224
    text (unicode on py2, str on py3) around 0MQ.
 
225
 
 
226
    Parameters
 
227
    ----------
 
228
    u : Python unicode string (unicode on py2, str on py3)
 
229
        The unicode string to send.
 
230
    flags : int, optional
 
231
        Any valid send flag.
 
232
    encoding : str [default: 'utf-8']
 
233
        The encoding to be used
 
234
    """
 
235
    if not isinstance(u, basestring):
 
236
        raise TypeError("unicode/str objects only")
 
237
    return self.send(u.encode(encoding), flags=flags, copy=copy)
 
238
 
 
239
def recv_string(self, flags=0, encoding='utf-8'):
 
240
    """s.recv_string(flags=0, encoding='utf-8')
 
241
 
 
242
    Receive a unicode string, as sent by send_string.
 
243
    
 
244
    Parameters
 
245
    ----------
 
246
    flags : int
 
247
        Any valid recv flag.
 
248
    encoding : str [default: 'utf-8']
 
249
        The encoding to be used
 
250
 
 
251
    Returns
 
252
    -------
 
253
    s : unicode string (unicode on py2, str on py3)
 
254
        The Python unicode string that arrives as encoded bytes.
 
255
    """
 
256
    msg = self.recv(flags=flags, copy=False)
 
257
    return codecs.decode(msg.bytes, encoding)
 
258
 
 
259
def send_pyobj(self, obj, flags=0, protocol=-1):
 
260
    """s.send_pyobj(obj, flags=0, protocol=-1)
 
261
 
 
262
    Send a Python object as a message using pickle to serialize.
 
263
 
 
264
    Parameters
 
265
    ----------
 
266
    obj : Python object
 
267
        The Python object to send.
 
268
    flags : int
 
269
        Any valid send flag.
 
270
    protocol : int
 
271
        The pickle protocol number to use. Default of -1 will select
 
272
        the highest supported number. Use 0 for multiple platform
 
273
        support.
 
274
    """
 
275
    msg = pickle.dumps(obj, protocol)
 
276
    return self.send(msg, flags)
 
277
 
 
278
def recv_pyobj(self, flags=0):
 
279
    """s.recv_pyobj(flags=0)
 
280
 
 
281
    Receive a Python object as a message using pickle to serialize.
 
282
 
 
283
    Parameters
 
284
    ----------
 
285
    flags : int
 
286
        Any valid recv flag.
 
287
 
 
288
    Returns
 
289
    -------
 
290
    obj : Python object
 
291
        The Python object that arrives as a message.
 
292
    """
 
293
    s = self.recv(flags)
 
294
    return pickle.loads(s)
 
295
 
 
296
def send_json(self, obj, flags=0):
 
297
    """s.send_json(obj, flags=0)
 
298
 
 
299
    Send a Python object as a message using json to serialize.
 
300
 
 
301
    Parameters
 
302
    ----------
 
303
    obj : Python object
 
304
        The Python object to send.
 
305
    flags : int
 
306
        Any valid send flag.
 
307
    """
 
308
    if jsonapi.jsonmod is None:
 
309
        raise ImportError('jsonlib{1,2}, json or simplejson library is required.')
 
310
    else:
 
311
        msg = jsonapi.dumps(obj)
 
312
        return self.send(msg, flags)
 
313
 
 
314
def recv_json(self, flags=0):
 
315
    """s.recv_json(flags=0)
 
316
 
 
317
    Receive a Python object as a message using json to serialize.
 
318
 
 
319
    Parameters
 
320
    ----------
 
321
    flags : int
 
322
        Any valid recv flag.
 
323
 
 
324
    Returns
 
325
    -------
 
326
    obj : Python object
 
327
        The Python object that arrives as a message.
 
328
    """
 
329
    if jsonapi.jsonmod is None:
 
330
        raise ImportError('jsonlib{1,2}, json or simplejson library is required.')
 
331
    else:
 
332
        msg = self.recv(flags)
 
333
        return jsonapi.loads(msg)
 
334
 
 
335
def poll(self, timeout=None, flags=POLLIN):
 
336
    """s.poll(timeout=None, flags=POLLIN)
 
337
 
 
338
    Poll the socket for events.  The default is to poll forever for incoming
 
339
    events.  Timeout is in milliseconds, if specified.
 
340
 
 
341
    Parameters
 
342
    ----------
 
343
    timeout : int [default: None]
 
344
        The timeout (in milliseconds) to wait for an event. If unspecified
 
345
        (or secified None), will wait forever for an event.
 
346
    flags : bitfield (int) [default: POLLIN]
 
347
        The event flags to poll for (any combination of POLLIN|POLLOUT).
 
348
        The default is to check for incoming events (POLLIN).
 
349
 
 
350
    Returns
 
351
    -------
 
352
    events : bitfield (int)
 
353
        The events that are ready and waiting.  Will be 0 if no events were ready
 
354
        by the time timeout was reached.
 
355
    """
 
356
 
 
357
    if self.closed:
 
358
        raise ZMQError(ENOTSUP)
 
359
 
 
360
    p = zmq.Poller()
 
361
    p.register(self, flags)
 
362
    evts = dict(p.poll(timeout))
 
363
    # return 0 if no events, otherwise return event bitfield
 
364
    return evts.get(self, 0)