Re: Re: class proposal
Christian Tismer <[email protected]>
| Newsgroups | gmane.comp.lang.prothon.user |
|---|---|
| Message-ID | <[email protected]> |
Hi Lenard, > I will explain here that I deliberately used the word 'type' differently > from its normal in Python meaning. This may have been a mistake. I appologize > for the confusion. I understand that the convensional Python meaning of 'type' > is a new-style class defined in C, such as 'int', 'map', and 'type' itself. But > I was at a loss for a general term for any instance of PyTypeObject, including > those that do not having ob_type set to PyType_Type. What is the correct term here? > Extension type? It would seem the word 'type' has been overloaded in Python. All objects are objects and have a type. Types are objects, too, and have a type. type type has its base set to object. Types with ob_type not set to PyType_Type are types, too, they just have a different meta-type than others. I don't see overloading, yet. > My approach was to explain Python starting a the byte-code interpreter level and > working up. This was to contrast it with Prothon, and to show how "classes" in > Python are built upon a lower level "type" system which the byte-code interpreter > understands. Python's bytecode interpreter had never understoof classes or types in any way. This was always delegated into special C modules. I still don't see the relevance of this detail. It doesn't matter whether you make every detail into a series of opcodes, or whether you compile byte code into machine code. That has nothing to do with the language. > On Wed, 23 Jun 2004 02:27:39 +0200 Christian Tismer <[email protected]> wrote: > > >>Lenard Lindstrom wrote: >> >>... >>[skipping a lot, only commenting on what I really know about] >> >>I'm sorry, but I have to contradict you multiple times. >>Please forgive me. >> >> >>>This is where all the confusion starts. In Python types and classes are not >>>the same thing. >> >>Wrong. In Python, there are still old-style classes which are >>slightly different in behavior, and really different because >>their type() is always class and their instance's type() is always >>instance, but they are just there for backward compatibility. >> > > I use the generic meaning of 'class'. And if I am not mistaken, classic > classes in 2.2 and up are really implemented on top of new-style classes. Not really. They are mixed into it. The new-style type implementation detects old-style class objects and delegates to the almost unchanged old code, basically. > Python 2.3.3 (#51, Jan 27 2004, 16:30:16) [MSC v.1200 32 bit (Intel)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>>>class C: pass > > ... > >>>>c=C() >>>>isinstance(c, object) > > True That's true for all objects. type has object as base: type.__base__ <type 'object'> >>New-style classes and types are *not* different, but the same thing. > > Again, I am using 'type' to mean any PyTypeObject instance. So do I. I don't get the problem, still. ... > I am distinguishing between methods accessible from within Python, which > are entered in a dictionary and the C functions of a PyTypeObject instance. But why is this a problem for you? The C functions of a PyTypeObject are of course accessible from within Python, since the type machinery creates wrappers for all C methods and puts them into the dictionary of the type. ... >>Sorry, please read typeobject.c . > > That is my point. typeobject.c is a separate C module from ceval.c. It defines a > particular instance of PyTypeObject. PyType_Type defines new-style class behavior, > not the ( byte-code ) interpreter. As said, the byte-code interpreter never did that, also not for old classes. They tried to keep the bytecode unchanged as much as possible, and tried to keep the interpreter simple, so the class design was by intent not put into the interpreter. ... > I did leave out a lot of details. The tp_base and tp_bases slot may be defined for > PyTypeObject but does the interpreter actually use then directly, let alone know > about them? Or is it there as a convenience for the PyType_Type slot functions? The bytecode interpreter uses direct access to object slots very rarely, only where speed was dictating it. In most cases, the protocol of object.h is used as the interface. > Could I define a PyTypeObject instance that does not actually use these slots? You mean the slots of the type object, not the __slots__, I think? Most of them can be overridden from Python. When you define a new type, the initialisation code does a lot of thinking about whether to use builtin C code or Python code which overrides. In the latter case, the builtin C slot of the new type object gets filled with a special C wrapper that calls back into the Python code accessible though the type __dict__. This is all the magic of the new "heap type". It is an extension of the old type obejct, providing a battery of extra slots, which are only accessed internally, and they are filled with wrappers, which either call the internal slot or the Python override from the dict. It has IMHO become the most difficult part of Python to understand, but also one of the most genial parts. I had a very hard time to extend this thing to my Stackless needs, while keeping the original structure binary equivalent. > I admit I am not clear on how new-style class types inherit through tp_base and > tp_bases. Does it involve slot promotion? Promotion by copying slots from base types? No. During type creation, all wrappers for internal methods or overridden methods are created and all slots are filled with either. Then the mro is built. For every attribute lookup, the mro is searched sequentially until something is found. >>Absolutely *YES* multiple inheritance, completely what classes had >>before, and much better. >>The basic type is object, which is common to all types and always >>compatible. All other types may or may not add to the binary basic >>object structure. > > > PyType_Object is inherited through the mro, not ob_type. So its importance > is only to PyTypeObject instances that are actually new-style classes. type inherits mro from object. This is an unbound method: >>> type.mro() Traceback (most recent call last): File "<interactive input>", line 1, in ? TypeError: descriptor 'mro' of 'type' object needs an argument >>> A "real " type is an instance of its meta type, and it gets mro as a bound method: >>> int.mro <built-in method mro of type object at 0x1E0CF7A8> >>> int.mro() [<type 'int'>, <type 'object'>] >>> Old-style classes don't know about mro, they have no access to it: >>> class A: ... pass ... >>> A.mro() Traceback (most recent call last): File "<interactive input>", line 1, in ? AttributeError: class A has no attribute 'mro' >>> This is so ,since old-style classes are just objects, no types. They are normal objects, compare to an int instance: >>> (5).mro() Traceback (most recent call last): File "<interactive input>", line 1, in ? AttributeError: 'int' object has no attribute 'mro' >>> BUT: >>> type(5).mro() [<type 'int'>, <type 'object'>] >>> type(A).mro() [<type 'classobj'>, <type 'object'>] You see, types have downgraded classes to simple instances which have their own way to deal with their own instances. ... >> >>> class a(int, str): >>... pass >>... >>Traceback (most recent call last): >> File "<interactive input>", line 1, in ? >>TypeError: multiple bases have instance lay-out conflict >> >>> >> > Is this enforced at the interpreter level, or by PyType_Type? Nothing complicated is enforced at the interpreter level, all the logic is in typeobject.c . ... > I have actually implemented Prothon like prototypes in Python using new-style > classes. I had to use indirect metaclassing and override __getattribute__, etc. to > make delegation (the prototype equivalence of inheritance) work correctly, but > it is a fair approximation. A proper, production quality, version would be implemented > as an extension type. It would be a new-style class type, but would define its own > delegation system for attribute lookup. That approach is just fine. >>Please don't be offended, but I couldn't leave things misunderstood. >> > > That is ok. I did not have the time to confirm all the details. Yes, many PyTypeObject > instances *are* new-style classes. But this is not a requirement. And the byte-code > interpreter does not know the difference. Right. It doesn't know almost anything, just how to call other methods which know what to do. all the best -- chris -- Christian Tismer :^) <mailto:[email protected]> Mission Impossible 5oftware : Have a break! Take a ride on Python's Johannes-Niemeyer-Weg 9a : *Starship* http://starship.python.net/ 14109 Berlin : PGP key -> http://wwwkeys.pgp.net/ work +49 30 89 09 53 34 home +49 30 802 86 56 mobile +49 173 24 18 776 PGP 0x57F3BF04 9064 F4E1 D754 C2FF 1619 305B C09C 5A3B 57F3 BF04 whom do you want to sponsor today? http://www.stackless.com/