[omniORB] Passing dictionary.
William Noon
noon@snow.nrcc.cornell.edu
Thu Jun 20 13:48:01 2002
On Thu, 20 Jun 2002 09:48:07, Duncan Grisby wrote:
>
> On Thursday 20 June, Nathaniel Smith wrote:
>
> > I think you misunderstood -- "dictionary" is Python-ese for "hash
> > table". It's a basic mapping type, and I've wondered what the best
> > way to send one down the wire is myself. I don't really have a good
> > answer, though; one option would of course be to wrap it in a CORBA
> > object with methods "get", "set", etc., but if you want to actually
> > send the whole dictionary across the wire, then you'll have to do some
> > "marshalling" by hand.
> >
> > Perhaps to send a dictionary mapping strings to strings, one could use
> > struct StrStrPair { string key, value; }
> > typedef sequence<StrStrPair> StrStrDictionary;
> > and then pack/unpack by hand on each end of the connection.
>
> Yes, that's a sensible representation for a Python dictionary. Of
> course, Python dictionaries can contain values with any types, and
> keys with a wide range of types, not just strings. To cope with all
> Python dictionaries in a single CORBA type, you'd have to use a
> sequence of structs of Anys. That would be a real pain, though.
>
> ILU had (has?) an interesting feature where if you have a sequence of
> structs, and the struct's member names are "key" and "value", it would
> map that to a Python dictionary, rather than the normal Python
> language mapping. I have resisted doing that sort of thing in
> omniORBpy since it's a bit too magic for my liking.
>
I used to use that ILU functionality all the time, but it didn't end
up in the CORBA <-> python mapping and I converted all the dictionaries
to:
struct NameAnyPair {string name; any value};
typedef sequence<NameAnyPair> FieldsDict;
This requires that all keys in the dictionary to be strings but the values
can be any object (defined in the idl). It is possible to pass a sequence
with several identical keys that would be overwritten in the resulting
python dictionary.
Filling the NameAnyPair sequence requires constructing any's for each value:
NameAny = Meta.MetaQuery.NameAnyPair
any = CORBA.Any
tc = CORBA.TypeCode
tc_short = CORBA.TC_short
tc_string = CORBA.TC_string
qual = [
NameAny('postal',any(tc_string,'NY')),
NameAny('clim_div_code',any(tc_string,'10')),
NameAny('var_major_id',any(tc_short,4)),
NameAny('begin_date',any(tc(ShortSeq),(2000,1,1))),
NameAny('end_date',any(tc(ShortSeq),(2000,7,1))),
]
A simple function to de-marshal the NameAnySeq to a python dictionary would
be as follows:
def NameAny_to_dict(na) :
ret = {}
for a in na :
ret[a.name] = a.value.value()
return ret
This will silently remove any duplicate keys in the sequence (keeping the
lastest in the sequence).
--Bill Noon
Northeast Regional Climate Center
Cornell University