The more I think about it (and re-read the tutorials), the more it seems to me that the name argument of most components in PyConstruct is misplaced. It should not be part of the construct::
foo = Struct("foo", UBInt32("bar"), UBInt16("baz") ) but part of the enclosing Struct. The simplest syntax is ('name', construct) tuples:: foo = Struct( ("bar", UBInt32), ("baz", UBInt16), ) It's tempting to try using assignment syntax:: foo = Struct( bar=UBInt32, baz=UBInt16, ) but that loses orders and envisionable hacks for recovering the order are too fragile. Forget it for now. That would fix several things that stick out from the general elegance of PyConstruct: * Some names are unused (e.g. inside Sequence or IfThenElse). * The name of the outermost Struct is repeated twice. * A name can be burrowed deep inside adpters and its effect on some enclosing Struct can be unobvious and magic. * Rename is a kludge. Having the name as part of a component complicates reuse. * Most "macro functions" take just the name as an argument, needlessly complicating them. With the name outside, many macro functions could simply be reusable singletons:: UBInt8 = FormatField(name, ">", "B") but if you don't like that, you can keep them all as functions of no arguments for consistency of use... Another clever side effect is that Struct nesting vs. embedding can be simply indicated by wrapping or not the inner Struct with a name tuple:: foo = Struct( Struct( ("bar", UBInt32), ), ("quux", Struct( ("baz", UBInt16), ), ) # this gives `bar` and `quux.baz` Unfortunately, this doesn't generalize to Sequence embedding, so we get only half a win here. If this indeed looks like an improvement, now (2.0) would be a good time to make the change (I'm willing to help with the rewriting). What do you think? -- Beni Cherniavsky <[EMAIL PROTECTED]> (I read email only on weekends)