diff options
author | Rafael H. Schloming <rhs@apache.org> | 2009-01-08 17:10:20 +0000 |
---|---|---|
committer | Rafael H. Schloming <rhs@apache.org> | 2009-01-08 17:10:20 +0000 |
commit | 27293b8e3624cb13fa346016b65f0b8a71b0279a (patch) | |
tree | 36d99e9e1f39715e0669834520ce638e3904b937 | |
parent | fc6840f32b54a81241fa91b0c0248ce395609ba6 (diff) | |
download | qpid-python-27293b8e3624cb13fa346016b65f0b8a71b0279a.tar.gz |
made codegen happen on module import rather than on object instantiation, this makes things like help(Session) much more useful
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@732760 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | python/qpid/connection.py | 23 | ||||
-rw-r--r-- | python/qpid/generator.py | 60 | ||||
-rw-r--r-- | python/qpid/invoker.py | 48 | ||||
-rw-r--r-- | python/qpid/session.py | 23 | ||||
-rw-r--r-- | python/qpid/spec.py | 2 |
5 files changed, 72 insertions, 84 deletions
diff --git a/python/qpid/connection.py b/python/qpid/connection.py index 4c9c02822a..6665e3e40c 100644 --- a/python/qpid/connection.py +++ b/python/qpid/connection.py @@ -23,9 +23,8 @@ from util import wait, notify from assembler import Assembler, Segment from codec010 import StringCodec from session import Session -from invoker import Invoker -from spec010 import Control, Command, load -from spec import default +from generator import control_invoker +from spec import SPEC from exceptions import * from logging import getLogger import delegates @@ -63,12 +62,9 @@ def sslwrap(sock): class Connection(Assembler): - def __init__(self, sock, spec=None, delegate=client, **args): + def __init__(self, sock, spec=SPEC, delegate=client, **args): Assembler.__init__(self, sslwrap(sock)) - if spec == None: - spec = load(default()) self.spec = spec - self.track = self.spec["track"] self.lock = RLock() self.attached = {} @@ -96,7 +92,7 @@ class Connection(Assembler): else: ssn = self.sessions.get(name) if ssn is None: - ssn = Session(name, self.spec, delegate=delegate) + ssn = Session(name, delegate=delegate) self.sessions[name] = ssn elif ssn.channel is not None: if force: @@ -189,23 +185,16 @@ class Connection(Assembler): log = getLogger("qpid.io.ctl") -class Channel(Invoker): +class Channel(control_invoker(SPEC)): def __init__(self, connection, id): self.connection = connection self.id = id self.session = None - def resolve_method(self, name): - inst = self.connection.spec.instructions.get(name) - if inst is not None and isinstance(inst, Control): - return self.METHOD, inst - else: - return self.ERROR, None - def invoke(self, type, args, kwargs): ctl = type.new(args, kwargs) - sc = StringCodec(self.connection.spec) + sc = StringCodec(self.spec) sc.write_control(ctl) self.connection.write_segment(Segment(True, True, type.segment_type, type.track, self.id, sc.encoded)) diff --git a/python/qpid/generator.py b/python/qpid/generator.py new file mode 100644 index 0000000000..307ea562d7 --- /dev/null +++ b/python/qpid/generator.py @@ -0,0 +1,60 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +import sys + +from spec010 import Control + +def METHOD(module, inst): + method = lambda self, *args, **kwargs: self.invoke(inst, args, kwargs) + if sys.version_info[:2] > (2, 3): + method.__name__ = inst.pyname + method.__doc__ = inst.pydoc + method.__module__ = module + return method + +def generate(spec, module, predicate=lambda x: True): + dict = {"spec": spec} + + for name, enum in spec.enums.items(): + dict[name] = enum + + for name, st in spec.structs_by_name.items(): + dict[name] = METHOD(module, st) + + for st in spec.structs.values(): + dict[st.name] = METHOD(module, st) + + for name, inst in spec.instructions.items(): + if predicate(inst): + dict[name] = METHOD(module, inst) + + return dict + +def invoker(name, spec, predicate=lambda x: True): + return type("%s_%s_%s" % (name, spec.major, spec.minor), + (), generate(spec, invoker.__module__, predicate)) + +def command_invoker(spec): + is_command = lambda cmd: cmd.track == spec["track.command"].value + return invoker("CommandInvoker", spec, is_command) + +def control_invoker(spec): + is_control = lambda inst: isinstance(inst, Control) + return invoker("ControlInvoker", spec, is_control) diff --git a/python/qpid/invoker.py b/python/qpid/invoker.py deleted file mode 100644 index 635f3ee769..0000000000 --- a/python/qpid/invoker.py +++ /dev/null @@ -1,48 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -import sys - -# TODO: need a better naming for this class now that it does the value -# stuff -class Invoker: - - def METHOD(self, name, resolved): - method = lambda *args, **kwargs: self.invoke(resolved, args, kwargs) - if sys.version_info[:2] > (2, 3): - method.__name__ = resolved.pyname - method.__doc__ = resolved.pydoc - method.__module__ = self.__class__.__module__ - self.__dict__[name] = method - return method - - def VALUE(self, name, resolved): - self.__dict__[name] = resolved - return resolved - - def ERROR(self, name, resolved): - raise AttributeError("%s instance has no attribute '%s'" % - (self.__class__.__name__, name)) - - def resolve_method(self, name): - return ERROR, None - - def __getattr__(self, name): - disp, resolved = self.resolve_method(name) - return disp(name, resolved) diff --git a/python/qpid/session.py b/python/qpid/session.py index 4a7ecbc28a..587a226aa1 100644 --- a/python/qpid/session.py +++ b/python/qpid/session.py @@ -18,7 +18,8 @@ # from threading import Condition, RLock, Lock, currentThread -from invoker import Invoker +from spec import SPEC +from generator import command_invoker from datatypes import RangedSet, Struct, Future from codec010 import StringCodec from assembler import Segment @@ -43,11 +44,10 @@ def server(*args): INCOMPLETE = object() -class Session(Invoker): +class Session(command_invoker(SPEC)): - def __init__(self, name, spec, auto_sync=True, timeout=10, delegate=client): + def __init__(self, name, auto_sync=True, timeout=10, delegate=client): self.name = name - self.spec = spec self.auto_sync = auto_sync self.timeout = timeout self.channel = None @@ -133,21 +133,6 @@ class Session(Invoker): finally: self.lock.release() - def resolve_method(self, name): - cmd = self.spec.instructions.get(name) - if cmd is not None and cmd.track == self.spec["track.command"].value: - return self.METHOD, cmd - else: - # XXX - for st in self.spec.structs.values(): - if st.name == name: - return self.METHOD, st - if self.spec.structs_by_name.has_key(name): - return self.METHOD, self.spec.structs_by_name[name] - if self.spec.enums.has_key(name): - return self.VALUE, self.spec.enums[name] - return self.ERROR, None - def invoke(self, type, args, kwargs): # XXX if not hasattr(type, "track"): diff --git a/python/qpid/spec.py b/python/qpid/spec.py index e6d914044c..cd76c70c5c 100644 --- a/python/qpid/spec.py +++ b/python/qpid/spec.py @@ -57,3 +57,5 @@ def load(specfile, *errata): return spec010.load(specfile, *errata) else: return spec08.load(specfile, *errata) + +SPEC = load(default()) |