Skip to content

Commit df77ec5

Browse files
committed
fixed circular import and empty ns hostname lookup
1 parent b7f80f4 commit df77ec5

13 files changed

Lines changed: 97 additions & 96 deletions

File tree

‎Pyro5/__init__.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
Pyro - Python Remote Objects. Copyright by Irmen de Jong (irmen@razorvine.net).
55
"""
66

7-
__version__ = "5.9"
7+
__version__ = "5.9.1"
88
__author__ = "Irmen de Jong"
99

1010

‎Pyro5/api.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66

77
from . import __version__
88
from .configure import global_config as config
9-
from .core import URI, locate_ns, resolve, type_meta, current_context
9+
from .core import URI, locate_ns, resolve, type_meta
1010
from .client import Proxy, BatchProxy, SerializedBlob
1111
from .server import Daemon, DaemonObject, callback, expose, behavior, oneway, serve
1212
from .nameserver import start_ns, start_ns_loop
1313
from .serializers import SerializerBase
14+
from .callcontext import current_context
1415

1516

1617
__all__ = ["config", "URI", "locate_ns", "resolve", "type_meta", "current_context",

‎Pyro5/callcontext.py‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import threading
2+
from . import errors
3+
4+
5+
# call context thread local
6+
class _CallContext(threading.local):
7+
def __init__(self):
8+
# per-thread initialization
9+
self.client = None
10+
self.client_sock_addr = None
11+
self.seq = 0
12+
self.msg_flags = 0
13+
self.serializer_id = 0
14+
self.annotations = {}
15+
self.response_annotations = {}
16+
self.correlation_id = None
17+
18+
def to_global(self):
19+
return dict(self.__dict__)
20+
21+
def from_global(self, values):
22+
self.client = values["client"]
23+
self.seq = values["seq"]
24+
self.msg_flags = values["msg_flags"]
25+
self.serializer_id = values["serializer_id"]
26+
self.annotations = values["annotations"]
27+
self.response_annotations = values["response_annotations"]
28+
self.correlation_id = values["correlation_id"]
29+
self.client_sock_addr = values["client_sock_addr"]
30+
31+
def track_resource(self, resource):
32+
"""keep a weak reference to the resource to be tracked for this connection"""
33+
if self.client:
34+
self.client.tracked_resources.add(resource)
35+
else:
36+
raise errors.PyroError("cannot track resource on a connectionless call")
37+
38+
def untrack_resource(self, resource):
39+
"""no longer track the resource for this connection"""
40+
if self.client:
41+
self.client.tracked_resources.discard(resource)
42+
else:
43+
raise errors.PyroError("cannot untrack resource on a connectionless call")
44+
45+
46+
current_context = _CallContext()
47+
"""the context object for the current call. (thread-local)"""

‎Pyro5/client.py‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import serpent
1010
import contextlib
1111
from . import config, core, serializers, protocol, errors, socketutil
12+
from .callcontext import current_context
1213
try:
1314
from greenlet import getcurrent as get_ident
1415
except ImportError:
@@ -71,7 +72,7 @@ def __init__(self, uri, connected_socket=None):
7172
# note: we're not clearing the client annotations dict here.
7273
# that is because otherwise it will be wiped if a new proxy is needed to connect PYRONAME uris.
7374
# clearing the response annotations is okay.
74-
core.current_context.response_annotations = {}
75+
current_context.response_annotations = {}
7576
if connected_socket:
7677
self.__pyroCreateConnection(False, connected_socket)
7778

@@ -196,12 +197,12 @@ def __pyroSetTimeout(self, timeout):
196197
def _pyroInvoke(self, methodname, vargs, kwargs, flags=0, objectId=None):
197198
"""perform the remote method call communication"""
198199
self.__check_owner()
199-
core.current_context.response_annotations = {}
200+
current_context.response_annotations = {}
200201
if self._pyroConnection is None:
201202
self.__pyroCreateConnection()
202203
serializer = serializers.serializers[self._pyroSerializer or config.SERIALIZER]
203204
objectId = objectId or self._pyroConnection.objectId
204-
annotations = core.current_context.annotations
205+
annotations = current_context.annotations
205206
if vargs and isinstance(vargs[0], SerializedBlob):
206207
# special serialization of a 'blob' that stays serialized
207208
data, flags = self.__serializeBlobArgs(vargs, kwargs, annotations, flags, objectId, methodname, serializer)
@@ -229,7 +230,7 @@ def _pyroInvoke(self, methodname, vargs, kwargs, flags=0, objectId=None):
229230
log.error(error)
230231
raise errors.SerializeError(error)
231232
if msg.annotations:
232-
core.current_context.response_annotations = msg.annotations
233+
current_context.response_annotations = msg.annotations
233234
if self._pyroRawWireResponse:
234235
return msg
235236
data = serializer.loads(msg.data)
@@ -285,7 +286,7 @@ def connect_and_handshake(conn):
285286
data = {"handshake": self._pyroHandshake, "object": uri.object}
286287
data = serializer.dumps(data)
287288
msg = protocol.SendingMessage(protocol.MSG_CONNECT, 0, self._pyroSeq, serializer.serializer_id,
288-
data, annotations=core.current_context.annotations)
289+
data, annotations=current_context.annotations)
289290
if config.LOGWIRE:
290291
protocol.log_wiredata(log, "proxy connect sending", msg)
291292
conn.send(msg.data)
@@ -320,7 +321,7 @@ def connect_and_handshake(conn):
320321
self._pyroValidateHandshake(handshake_response)
321322
log.debug("connected to %s - %s - %s", self._pyroUri, conn.family(), "SSL" if sslContext else "unencrypted")
322323
if msg.annotations:
323-
core.current_context.response_annotations = msg.annotations
324+
current_context.response_annotations = msg.annotations
324325
else:
325326
conn.close()
326327
err = "cannot connect to %s: invalid msg type %d received" % (connect_location, msg.type)

‎Pyro5/compatibility/Pyro4.py‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,6 @@
1919
Pyro - Python Remote Objects. Copyright by Irmen de Jong (irmen@razorvine.net).
2020
"""
2121

22-
# the symbols that were available in Pyro4 as Pyro4.* :
23-
# from Pyro4.core import URI, Proxy, Daemon, callback, batch, asyncproxy, oneway, expose, behavior, current_context
24-
# from Pyro4.core import _locateNS as locateNS, _resolve as resolve
25-
# from Pyro4.futures import Future
26-
2722
import sys
2823
import ipaddress
2924

‎Pyro5/core.py‎

Lines changed: 4 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@
99
import contextlib
1010
import ipaddress
1111
import socket
12-
import threading
1312
import random
1413
import serpent
1514
from typing import Union, Optional
1615
from . import config, errors, socketutil, serializers, nameserver
1716

1817

19-
__all__ = ["URI", "DAEMON_NAME", "NAMESERVER_NAME", "current_context", "resolve", "locate_ns", "type_meta"]
18+
__all__ = ["URI", "DAEMON_NAME", "NAMESERVER_NAME", "resolve", "locate_ns", "type_meta"]
2019

2120
log = logging.getLogger("Pyro5.core")
2221

@@ -203,13 +202,11 @@ def resolve(uri: Union[str, URI], delay_time: float = 0.0) -> URI:
203202
raise errors.PyroError("invalid uri protocol")
204203

205204

206-
from . import client # circular import...
207-
208-
209205
def locate_ns(host: Union[str, ipaddress.IPv4Address, ipaddress.IPv6Address] = "",
210-
port: Optional[int] = None, broadcast: bool = True) -> client.Proxy:
206+
port: Optional[int] = None, broadcast: bool = True) -> "client.Proxy":
211207
"""Get a proxy for a name server somewhere in the network."""
212-
if host == "":
208+
from . import client
209+
if not host:
213210
# first try localhost if we have a good chance of finding it there
214211
if config.NS_HOST in ("localhost", "::1") or config.NS_HOST.startswith("127."):
215212
if ":" in config.NS_HOST: # ipv6
@@ -295,48 +292,3 @@ def type_meta(class_or_object, prefix="class:"):
295292
if hasattr(class_or_object, "__class__"):
296293
return type_meta(class_or_object.__class__)
297294
return frozenset()
298-
299-
300-
# call context thread local
301-
class _CallContext(threading.local):
302-
def __init__(self):
303-
# per-thread initialization
304-
self.client = None
305-
self.client_sock_addr = None
306-
self.seq = 0
307-
self.msg_flags = 0
308-
self.serializer_id = 0
309-
self.annotations = {}
310-
self.response_annotations = {}
311-
self.correlation_id = None
312-
313-
def to_global(self):
314-
return dict(self.__dict__)
315-
316-
def from_global(self, values):
317-
self.client = values["client"]
318-
self.seq = values["seq"]
319-
self.msg_flags = values["msg_flags"]
320-
self.serializer_id = values["serializer_id"]
321-
self.annotations = values["annotations"]
322-
self.response_annotations = values["response_annotations"]
323-
self.correlation_id = values["correlation_id"]
324-
self.client_sock_addr = values["client_sock_addr"]
325-
326-
def track_resource(self, resource):
327-
"""keep a weak reference to the resource to be tracked for this connection"""
328-
if self.client:
329-
self.client.tracked_resources.add(resource)
330-
else:
331-
raise errors.PyroError("cannot track resource on a connectionless call")
332-
333-
def untrack_resource(self, resource):
334-
"""no longer track the resource for this connection"""
335-
if self.client:
336-
self.client.tracked_resources.discard(resource)
337-
else:
338-
raise errors.PyroError("cannot untrack resource on a connectionless call")
339-
340-
341-
current_context = _CallContext()
342-
"""the context object for the current call. (thread-local)"""

‎Pyro5/nsc.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def cmd_yplookup_any():
104104
def main(args=None):
105105
from argparse import ArgumentParser
106106
parser = ArgumentParser(description="Pyro name server control utility.")
107-
parser.add_argument("-n", "--host", dest="host", help="hostname of the NS")
107+
parser.add_argument("-n", "--host", dest="host", help="hostname of the NS", default="")
108108
parser.add_argument("-p", "--port", dest="port", type=int, help="port of the NS (or bc-port if host isn't specified)")
109109
parser.add_argument("-u", "--unixsocket", help="Unix domain socket name of the NS")
110110
parser.add_argument("-v", "--verbose", action="store_true", dest="verbose", help="verbose output")

‎Pyro5/protocol.py‎

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import zlib
3939
import uuid
4040
from . import config, errors
41+
from .callcontext import current_context
4142

4243

4344
log = logging.getLogger("Pyro5.protocol")
@@ -66,9 +67,6 @@
6667
_empty_correlation_id = b"\0" * 16
6768

6869

69-
from . import core # circular import...
70-
71-
7270
class SendingMessage:
7371
"""Wire protocol message that will be sent."""
7472

@@ -86,9 +84,9 @@ def __init__(self, msgtype, flags, seq, serializer_id, payload, annotations=None
8684
total_size = len(payload) + annotations_size
8785
if total_size > config.MAX_MESSAGE_SIZE:
8886
raise errors.ProtocolError("message too large ({:d}, max={:d})".format(total_size, config.MAX_MESSAGE_SIZE))
89-
if core.current_context.correlation_id:
87+
if current_context.correlation_id:
9088
flags |= FLAGS_CORR_ID
91-
self.corr_id = core.current_context.correlation_id.bytes
89+
self.corr_id = current_context.correlation_id.bytes
9290
else:
9391
self.corr_id = _empty_correlation_id
9492
header_data = struct.pack(_header_format, b"PYRO", PROTOCOL_VERSION, msgtype, serializer_id, flags, seq,

‎Pyro5/server.py‎

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import ipaddress
1919
from typing import Callable, Tuple, Union, Optional, Dict, Any, Sequence, Set
2020
from . import config, core, errors, serializers, socketutil, protocol, client
21-
21+
from .callcontext import current_context
2222

2323
__all__ = ["Daemon", "DaemonObject", "callback", "expose", "behavior", "oneway", "serve"]
2424

@@ -175,7 +175,7 @@ def get_next_stream_item(self, streamId):
175175
client, timestamp, linger_timestamp, stream = self.daemon.streaming_responses[streamId]
176176
if client is None:
177177
# reset client connection association (can be None if proxy disconnected)
178-
self.daemon.streaming_responses[streamId] = (core.current_context.client, timestamp, 0, stream)
178+
self.daemon.streaming_responses[streamId] = (current_context.client, timestamp, 0, stream)
179179
try:
180180
return next(stream)
181181
except Exception:
@@ -331,9 +331,9 @@ def _handshake(self, conn, denied_reason=None):
331331
if config.LOGWIRE:
332332
protocol.log_wiredata(log, "daemon handshake received", msg)
333333
if msg.flags & protocol.FLAGS_CORR_ID:
334-
core.current_context.correlation_id = uuid.UUID(bytes=msg.corr_id)
334+
current_context.correlation_id = uuid.UUID(bytes=msg.corr_id)
335335
else:
336-
core.current_context.correlation_id = uuid.uuid4()
336+
current_context.correlation_id = uuid.uuid4()
337337
serializer_id = msg.serializer_id
338338
serializer = serializers.serializers_by_id[serializer_id]
339339
data = serializer.loads(msg.data)
@@ -397,9 +397,9 @@ def handleRequest(self, conn):
397397
request_seq = msg.seq
398398
request_serializer_id = msg.serializer_id
399399
if msg.flags & protocol.FLAGS_CORR_ID:
400-
core.current_context.correlation_id = uuid.UUID(bytes=msg.corr_id)
400+
current_context.correlation_id = uuid.UUID(bytes=msg.corr_id)
401401
else:
402-
core.current_context.correlation_id = uuid.uuid4()
402+
current_context.correlation_id = uuid.uuid4()
403403
if config.LOGWIRE:
404404
protocol.log_wiredata(log, "daemon wiredata received", msg)
405405
if msg.type == protocol.MSG_PING:
@@ -416,16 +416,16 @@ def handleRequest(self, conn):
416416
else:
417417
# normal deserialization of remote call arguments
418418
objId, method, vargs, kwargs = serializer.loadsCall(msg.data)
419-
core.current_context.client = conn
419+
current_context.client = conn
420420
try:
421421
# store, because on oneway calls, socket will be disconnected:
422-
core.current_context.client_sock_addr = conn.sock.getpeername()
422+
current_context.client_sock_addr = conn.sock.getpeername()
423423
except socket.error:
424-
core.current_context.client_sock_addr = None # sometimes getpeername() doesn't work...
425-
core.current_context.seq = msg.seq
426-
core.current_context.annotations = msg.annotations
427-
core.current_context.msg_flags = msg.flags
428-
core.current_context.serializer_id = msg.serializer_id
424+
current_context.client_sock_addr = None # sometimes getpeername() doesn't work...
425+
current_context.seq = msg.seq
426+
current_context.annotations = msg.annotations
427+
current_context.msg_flags = msg.flags
428+
current_context.serializer_id = msg.serializer_id
429429
del msg # invite GC to collect the object, don't wait for out-of-scope
430430
obj = self.objectsById.get(objId)
431431
if obj is not None:
@@ -489,7 +489,7 @@ def handleRequest(self, conn):
489489
response_flags |= protocol.FLAGS_BATCH
490490
msg = protocol.SendingMessage(protocol.MSG_RESULT, response_flags, request_seq, serializer.serializer_id, data,
491491
annotations=self.__annotations())
492-
core.current_context.response_annotations = {}
492+
current_context.response_annotations = {}
493493
if config.LOGWIRE:
494494
protocol.log_wiredata(log, "daemon wiredata sending", msg)
495495
conn.send(msg.data)
@@ -753,7 +753,7 @@ def combine(self, daemon):
753753
self.transportServer.combine_loop(daemon.transportServer)
754754

755755
def __annotations(self):
756-
annotations = core.current_context.response_annotations
756+
annotations = current_context.response_annotations
757757
annotations.update(self.annotations())
758758
return annotations
759759

@@ -965,15 +965,15 @@ class _OnewayCallThread(threading.Thread):
965965
def __init__(self, pyro_method, vargs, kwargs, pyro_daemon, pyro_client_sock):
966966
super(_OnewayCallThread, self).__init__(target=self._methodcall, name="oneway-call")
967967
self.daemon = True
968-
self.parent_context = core.current_context.to_global()
968+
self.parent_context = current_context.to_global()
969969
self.pyro_daemon = pyro_daemon
970970
self.pyro_client_sock = pyro_client_sock
971971
self.pyro_method = pyro_method
972972
self.pyro_vargs = vargs
973973
self.pyro_kwars = kwargs
974974

975975
def run(self):
976-
core.current_context.from_global(self.parent_context)
976+
current_context.from_global(self.parent_context)
977977
super(_OnewayCallThread, self).run()
978978

979979
def _methodcall(self):

0 commit comments

Comments
 (0)