diff options
| author | Rafael H. Schloming <rhs@apache.org> | 2008-03-10 19:12:09 +0000 |
|---|---|---|
| committer | Rafael H. Schloming <rhs@apache.org> | 2008-03-10 19:12:09 +0000 |
| commit | 713c0c114f8d344beb58d5f99d0cb602485399cf (patch) | |
| tree | da91f2d82f9bce5f5939d18db3526851ffd2ff95 /python/qpid | |
| parent | aeb6df01fad88c3202c9e30205ec60801d672d9c (diff) | |
| download | qpid-python-713c0c114f8d344beb58d5f99d0cb602485399cf.tar.gz | |
renamed datatypes.Struct.type -> datatypes.Struct._type; this avoids naming conflicts with metadata-driven fields; moved argument validation -> datatypes.Struct and improved error checking; improved datatypes.Struct.__repr__
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@635660 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'python/qpid')
| -rw-r--r-- | python/qpid/assembler.py | 4 | ||||
| -rw-r--r-- | python/qpid/codec010.py | 27 | ||||
| -rw-r--r-- | python/qpid/connection010.py | 2 | ||||
| -rw-r--r-- | python/qpid/datatypes.py | 47 | ||||
| -rw-r--r-- | python/qpid/delegates.py | 2 | ||||
| -rw-r--r-- | python/qpid/session.py | 11 | ||||
| -rw-r--r-- | python/qpid/spec010.py | 45 |
7 files changed, 75 insertions, 63 deletions
diff --git a/python/qpid/assembler.py b/python/qpid/assembler.py index 1a480698c8..9f8bc4bd8a 100644 --- a/python/qpid/assembler.py +++ b/python/qpid/assembler.py @@ -46,9 +46,9 @@ class Segment: def decode_command(self, spec): sc = StringCodec(spec, self.payload) - cmd = sc.read_command() + hdr, cmd = sc.read_command() cmd.id = self.id - return cmd + return hdr, cmd def decode_header(self, spec): sc = StringCodec(spec, self.payload) diff --git a/python/qpid/codec010.py b/python/qpid/codec010.py index 27df9db974..60adbdc2e4 100644 --- a/python/qpid/codec010.py +++ b/python/qpid/codec010.py @@ -18,7 +18,7 @@ # from packer import Packer -from datatypes import RangedSet +from datatypes import RangedSet, Struct class CodecException(Exception): pass @@ -184,27 +184,32 @@ class Codec(Packer): def read_struct32(self): size = self.read_uint32() code = self.read_uint16() - struct = self.spec.structs[code] - return struct.decode_fields(self) + type = self.spec.structs[code] + fields = type.decode_fields(self) + return Struct(type, **fields) def write_struct32(self, value): sc = StringCodec(self.spec) - sc.write_uint16(value.type.code) - value.type.encode_fields(sc, value) + sc.write_uint16(value._type.code) + value._type.encode_fields(sc, value) self.write_vbin32(sc.encoded) def read_control(self): cntrl = self.spec.controls[self.read_uint16()] return cntrl.decode(self) - def write_control(self, type, ctrl): + def write_control(self, ctrl): + type = ctrl._type self.write_uint16(type.code) type.encode(self, ctrl) def read_command(self): - cmd = self.spec.commands[self.read_uint16()] - return cmd.decode(self) - def write_command(self, type, cmd): - self.write_uint16(type.code) - type.encode(self, cmd) + type = self.spec.commands[self.read_uint16()] + hdr = self.spec["session.header"].decode(self) + cmd = type.decode(self) + return hdr, cmd + def write_command(self, hdr, cmd): + self.write_uint16(cmd._type.code) + hdr._type.encode(self, hdr) + cmd._type.encode(self, cmd) def read_size(self, width): if width > 0: diff --git a/python/qpid/connection010.py b/python/qpid/connection010.py index 022ef8e411..1235476b82 100644 --- a/python/qpid/connection010.py +++ b/python/qpid/connection010.py @@ -166,7 +166,7 @@ class Channel(Invoker): def invoke(self, type, args, kwargs): cntrl = type.new(args, kwargs) sc = StringCodec(self.connection.spec) - sc.write_control(type, cntrl) + sc.write_control(cntrl) self.connection.write_segment(Segment(True, True, type.segment_type, type.track, self.id, sc.encoded)) diff --git a/python/qpid/datatypes.py b/python/qpid/datatypes.py index e9973b4cc8..45944a2494 100644 --- a/python/qpid/datatypes.py +++ b/python/qpid/datatypes.py @@ -21,15 +21,48 @@ import threading class Struct: - def __init__(self, fields): - self.__dict__ = fields + def __init__(self, _type, *args, **kwargs): + if len(args) > len(_type.fields): + raise TypeError("%s() takes at most %s arguments (%s given)" % + (_type.name, len(_type.fields), len(args))) - def __repr__(self): - return "Struct(%s)" % ", ".join(["%s=%r" % (k, v) - for k, v in self.__dict__.items()]) + self._type = _type + + idx = 0 + for field in _type.fields: + if idx < len(args): + arg = args[idx] + if kwargs.has_key(field.name): + raise TypeError("%s() got multiple values for keyword argument '%s'" % + (_type.name, field.name)) + elif kwargs.has_key(field.name): + arg = kwargs.pop(field.name) + else: + arg = field.default() + setattr(self, field.name, arg) + idx += 1 - def fields(self): - return self.__dict__ + if kwargs: + unexpected = kwargs.keys()[0] + raise TypeError("%s() got an unexpected keywoard argument '%s'" % + (_type.name, unexpected)) + + def __getitem__(self, name): + return getattr(self, name) + + def __setitem__(self, name, value): + if not hasattr(self, name): + raise AttributeError("'%s' object has no attribute '%s'" % + (self._type.name, name)) + setattr(self, name, value) + + def __repr__(self): + fields = [] + for f in self._type.fields: + v = self[f.name] + if f.type.is_present(v): + fields.append("%s=%r" % (f.name, v)) + return "%s(%s)" % (self._type.name, ", ".join(fields)) class Message: diff --git a/python/qpid/delegates.py b/python/qpid/delegates.py index d1f615a3fa..8de7141962 100644 --- a/python/qpid/delegates.py +++ b/python/qpid/delegates.py @@ -38,7 +38,7 @@ class Delegate: if seg.track == self.control: cntrl = seg.decode(self.spec) - attr = cntrl.type.qname.replace(".", "_") + attr = cntrl._type.qname.replace(".", "_") getattr(self, attr)(ch, cntrl) elif ssn is None: ch.session_detached() diff --git a/python/qpid/session.py b/python/qpid/session.py index 7a84fa601d..8374b8cd3d 100644 --- a/python/qpid/session.py +++ b/python/qpid/session.py @@ -129,7 +129,8 @@ class Session(Invoker): cmd = type.new(args, kwargs) sc = StringCodec(self.spec) - sc.write_command(type, cmd) + hdr = Struct(self.spec["session.header"]) + sc.write_command(hdr, cmd) seg = Segment(True, (message == None or (message.headers == None and message.body == None)), @@ -174,10 +175,10 @@ class Session(Invoker): def dispatch(self, assembly): segments = assembly[:] - cmd = assembly.pop(0).decode(self.spec) + hdr, cmd = assembly.pop(0).decode(self.spec) args = [] - for st in cmd.type.segments: + for st in cmd._type.segments: if assembly: seg = assembly[0] if seg.type == st.segment_type: @@ -188,10 +189,10 @@ class Session(Invoker): assert len(assembly) == 0 - attr = cmd.type.qname.replace(".", "_") + attr = cmd._type.qname.replace(".", "_") result = getattr(self.delegate, attr)(cmd, *args) - if cmd.type.result: + if cmd._type.result: self.execution_result(cmd.id, result) if result is not INCOMPLETE: diff --git a/python/qpid/spec010.py b/python/qpid/spec010.py index b84be7a047..815c1d064a 100644 --- a/python/qpid/spec010.py +++ b/python/qpid/spec010.py @@ -188,34 +188,18 @@ class Composite(Type, Coded): self.pack = pack def new(self, args, kwargs): - if len(args) > len(self.fields): - raise TypeError("%s takes at most %s arguments (%s given)" % - (self.name, len(self.fields), len(self.args))) - - result = {"type": self} - - for a, f, in zip(args, self.fields): - result[f.name] = a - - for k, v in kwargs.items(): - f = self.named.get(k) - if f == None: - raise TypeError("%s got an unexpected keyword argument '%s'" % - (self.name, k)) - result[f.name] = v - - return datatypes.Struct(result) + return datatypes.Struct(self, *args, **kwargs) def decode(self, codec): codec.read_size(self.size) - return self.decode_fields(codec) + return datatypes.Struct(self, **self.decode_fields(codec)) def decode_fields(self, codec): flags = 0 for i in range(self.pack): flags |= (codec.read_uint8() << 8*i) - result = {"type": self} + result = {} for i in range(len(self.fields)): f = self.fields[i] @@ -223,7 +207,7 @@ class Composite(Type, Coded): result[f.name] = f.type.decode(codec) else: result[f.name] = None - return datatypes.Struct(result) + return result def encode(self, codec, value): sc = StringCodec(self.spec) @@ -231,12 +215,11 @@ class Composite(Type, Coded): codec.write_size(self.size, len(sc.encoded)) codec.write(sc.encoded) - def encode_fields(self, codec, value): - values = value.__dict__ + def encode_fields(self, codec, values): flags = 0 for i in range(len(self.fields)): f = self.fields[i] - if f.type.is_present(values.get(f.name)): + if f.type.is_present(values[f.name]): flags |= (0x1 << i) for i in range(self.pack): codec.write_uint8((flags >> 8*i) & 0xFF) @@ -253,6 +236,9 @@ class Field(Named, Node, Lookup): self.type = type self.exceptions = [] + def default(self): + return None + def register(self, node): Named.register(self, node) node.fields.append(self) @@ -328,23 +314,10 @@ class Command(Instruction): def register(self, node): Instruction.register(self, node) node.commands.append(self) - self.header = self.spec["session.header"] self.spec.commands[self.code] = self self.segment_type = self.spec["segment_type.command"].value self.track = self.spec["track.command"].value - def decode(self, codec): - hdr = self.header.decode(codec) - args = Instruction.decode(self, codec) - result = {} - result.update(hdr.fields()) - result.update(args.fields()) - return datatypes.Struct(result) - - def encode(self, codec, cmd): - self.header.encode(codec, cmd) - Instruction.encode(self, codec, cmd) - class Header(Segment, Node): def __init__(self, children): |
