
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