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)

לענות