[pypy-dev] Builtin types

Bengt Richter bokr at oz.net
Fri Jan 24 06:07:14 CET 2003


At 01:43 2003-01-24 +0100, Christian Tismer wrote:
>Scott Fenton wrote:
>>Hello all. While trying to mix up some more stuff for
>>__builtin__, I came up with an interesting problem.
>>The solution I found for classmethod (using google on
>>c.l.python, since I couldn't figure it out myself) requires that classes that use it
>>must derive from object.
>
>No, this is not true.
>classmethod works for every kind of class,
>may it be a newstyle class, triggered by
>- deriving from object
>- using __slots__
>- deriving from a builtin type or a descendant
>- did I forget something?
>or a "classic" class, it always works.
>For reference, see
>http://www.python.org/2.2/descrintro.html
>
>>That made me wonder, could
>>we just automatically derive everything from object
>>in Minimal? The big problem with doing this in CPython,
>>as I understand it, is extensions that need to be
>>converted, but we don't have that problem here, obviously.
>>So would it be alright if I went ahead and used this code
>>as if everything derived from object?
>
>No, sorry. object is just a special case for deriving a
>new-style class, see above.
>They can also be created by deriving from builtin types,
>or by using __slots__.
>
>Furthermore, I'm going to propose an extension to the new
>class system (at least for the MiniPy prototype) that goes
>a bit further:
>- __slots__ should get the ability to denote the type of
>  a slot to be generated, especially ctypes types
>- it should be possible to derive a class from nothing,
>  not even from object or classic, but I'd like to describe
>  a plain C structure by classes.
>
>The latter will allow to define the object class and all
>builtin types with the same machinery.

I have some thoughts for decribing C structures (and anything else
digital) in a canonical abstract way. I'll call such a decription
a meta-representation, and a function that produces it from a Python
object is meta_repr(python_object) => meta_rep_obj. The reverse
operation is meta_eval ;-)

The basis for meta_repr is that it capture and meta-represent
(type, id, value) for an object in a pure abstract form.
The abstract basis for storing the information is a bitvector
object with attribute names that specify slices of the bitvector.
I.e., there is an effective dict like {'slicename':(lo,hi)} and
__getattr__ uses it so that bvec.slicename refers to bvec[lo:hi] etc.
This is pure and abstract data, but you can see that interpreted
little-endianly you can very straightforwardly lay out a C struct
with whatever field widths and alignments you want.

I also want to make a way to create subclasses of the base bitvector
class that can have specified size and named slices as class variable
info shared by instances. This is very analogous to a C struct
definition, and BTW also permits union by just defining overlapping
named slices.

BTW2, there is also a natural way to iterate based on a slice name --
i.e., just walk successive contiguous same-size slices to some limit,
starting with the one defined by a name (which doesn't have to start at
bit 0 of the whole, of course, so you can get embedded arrays of bit
fields starting anywhere). Hence a giant bitvector with a slice
defined by byte=(16,24) could iterate in 8-bit bytes starting at bit 16.
meta_eval-ing such a byte sequence meta-representation together with
type and id would produce a Python character or string.

If Psyco could deal with these meta_representations in a fine-tuned way,
it might be possible to have very abstract representations of things and
yet generate efficient bit-twiddling assembler level stuff, and, as you
said, one consistent mechanism.

One nice thing would be to be able to define machine instructions in
terms of a few classes for different basic formats, with particular
bit fields named right out of the book. Same for floating point doubles,
etc. Packing code would be appending bit vectors, etc. Fortunately
intel is little-endian, so there is a simple mapping to the most common
machine stuff, but even if that were not so, the correspondence between
an abstract bit list and an abstract integer represented as an ordered
set of binary coefficients for powers of 2 just naturally sums little-
endianly by sum=0; for i in range(len(bitvec)): sum += bitvec[i]*2**i
Though of course that's not the most efficient way to compute it.

Anyway, this meta-repr/meta_eval idea is only half baked, but
in case you wanted to consider it, I wanted to offer it before
you are all finished ;-)

There is a bitvec.py in an old demo directory that I think I will
cannibalize for a good deal of bit vector stuff, though I think I
would want to base the data in a final version on arrays of ints
that would map more naturally to arrays of machine ints instead
of using  Python longs. But for prototyping it doesn't matter.

I still have to mull the class factory or perhaps metaclass stuff
for creating classes whose instances will share bit slice name
definitions. Also the best way to capture nested composition and
naming or whole and sub-parts, when it's done by composition instead
of one flat definition. BTW, it seems pickling and marshalling are
also quite related, but I haven't thought about that.

Interestingly, meta_repr produces a python object, so what does, e.g.,
meta_repr(meta_repr(123)) produce? It has to make sense ;-)

I am mulling the encoding of type and id along with value into some
composite meta_repr representation to represent a full object...

Also the meaning of mixed structures, like an ordinary Python list
of objects produced by meta_repr. It should be legal, but you have to
keep the tin foil in good repair ;-)

Please use what might further the project, and ignore the rest. But
besides the possible use PyPython, would named-slice abstract bit
vectors have a chance as a PEP as a way to express fine grain abstract
digital info?

Best,
Bengt



More information about the Pypy-dev mailing list