1 /***************************************************************************** 2 3 Copyright (c) 1996-2002 Zope Foundation and Contributors. 4 All Rights Reserved. 5 6 This software is subject to the provisions of the Zope Public License, 7 Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. 8 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED 9 WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 10 WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS 11 FOR A PARTICULAR PURPOSE 12 13 ****************************************************************************/ 14 15 /* 16 17 $Id$ 18 19 Extension Class Definitions 20 21 Implementing base extension classes 22 23 A base extension class is implemented in much the same way that an 24 extension type is implemented, except: 25 26 - The include file, 'ExtensionClass.h', must be included. 27 28 - The type structure is declared to be of type 29 'PyExtensionClass', rather than of type 'PyTypeObject'. 30 31 - The type structure has an additional member that must be defined 32 after the documentation string. This extra member is a method chain 33 ('PyMethodChain') containing a linked list of method definition 34 ('PyMethodDef') lists. Method chains can be used to implement 35 method inheritance in C. Most extensions don't use method chains, 36 but simply define method lists, which are null-terminated arrays 37 of method definitions. A macro, 'METHOD_CHAIN' is defined in 38 'ExtensionClass.h' that converts a method list to a method chain. 39 (See the example below.) 40 41 - Module functions that create new instances must be replaced by an 42 '__init__' method that initializes, but does not create storage for 43 instances. 44 45 - The extension class must be initialized and exported to the module 46 with:: 47 48 PyExtensionClass_Export(d,"name",type); 49 50 where 'name' is the module name and 'type' is the extension class 51 type object. 52 53 Attribute lookup 54 55 Attribute lookup is performed by calling the base extension class 56 'getattr' operation for the base extension class that includes C 57 data, or for the first base extension class, if none of the base 58 extension classes include C data. 'ExtensionClass.h' defines a 59 macro 'Py_FindAttrString' that can be used to find an object's 60 attributes that are stored in the object's instance dictionary or 61 in the object's class or base classes:: 62 63 v = Py_FindAttrString(self,name); 64 65 In addition, a macro is provided that replaces 'Py_FindMethod' 66 calls with logic to perform the same sort of lookup that is 67 provided by 'Py_FindAttrString'. 68 69 Linking 70 71 The extension class mechanism was designed to be useful with 72 dynamically linked extension modules. Modules that implement 73 extension classes do not have to be linked against an extension 74 class library. The macro 'PyExtensionClass_Export' imports the 75 'ExtensionClass' module and uses objects imported from this module 76 to initialize an extension class with necessary behavior. 77 78 */ 79 80 #ifndef EXTENSIONCLASS_H 81 #define EXTENSIONCLASS_H 82 83 #include "Python.h" 84 #include "import.h" 85 86 /* Declarations for objects of type ExtensionClass */ 87 88 #define EC PyTypeObject 89 #define PyExtensionClass PyTypeObject 90 91 #define EXTENSIONCLASS_BINDABLE_FLAG 1 << 2 92 #define EXTENSIONCLASS_NOINSTDICT_FLAG 1 << 5 93 94 typedef struct { 95 PyObject_HEAD 96 } _emptyobject; 97 98 static struct ExtensionClassCAPIstruct { 99 100 /***************************************************************************** 101 102 WARNING: THIS STRUCT IS PRIVATE TO THE EXTENSION CLASS INTERFACE 103 IMPLEMENTATION AND IS SUBJECT TO CHANGE !!! 104 105 *****************************************************************************/ 106 107 108 PyObject *(*EC_findiattrs_)(PyObject *self, char *cname); 109 int (*PyExtensionClass_Export_)(PyObject *dict, char *name, 110 PyTypeObject *typ); 111 PyObject *(*PyECMethod_New_)(PyObject *callable, PyObject *inst); 112 PyExtensionClass *ECBaseType_; 113 PyExtensionClass *ECExtensionClassType_; 114 } *PyExtensionClassCAPI = NULL; 115 116 #define ECBaseType (PyExtensionClassCAPI->ECBaseType_) 117 #define ECExtensionClassType (PyExtensionClassCAPI->ECExtensionClassType_) 118 119 /* Following are macros that are needed or useful for defining extension 120 classes: 121 */ 122 123 /* This macro redefines Py_FindMethod to do attribute for an attribute 124 name given by a C string lookup using extension class meta-data. 125 This is used by older getattr implementations. 126 127 This macro is used in base class implementations of tp_getattr to 128 lookup methods or attributes that are not managed by the base type 129 directly. The macro is generally used to search for attributes 130 after other attribute searches have failed. 131 132 Note that in Python 1.4, a getattr operation may be provided that 133 uses an object argument. Classes that support this new operation 134 should use Py_FindAttr. 135 */ 136 137 #define EC_findiattrs (PyExtensionClassCAPI->EC_findiattrs_) 138 139 #define Py_FindMethod(M,SELF,NAME) (EC_findiattrs((SELF),(NAME))) 140 141 /* Do method or attribute lookup for an attribute name given by a C 142 string using extension class meta-data. 143 144 This macro is used in base class implementations of tp_getattro to 145 lookup methods or attributes that are not managed by the base type 146 directly. The macro is generally used to search for attributes 147 after other attribute searches have failed. 148 149 Note that in Python 1.4, a getattr operation may be provided that 150 uses an object argument. Classes that support this new operation 151 should use Py_FindAttr. 152 */ 153 #define Py_FindAttrString(SELF,NAME) (EC_findiattrs((SELF),(NAME))) 154 155 /* Do method or attribute lookup using extension class meta-data. 156 157 This macro is used in base class implementations of tp_getattr to 158 lookup methods or attributes that are not managed by the base type 159 directly. The macro is generally used to search for attributes 160 after other attribute searches have failed. */ 161 #define Py_FindAttr (ECBaseType->tp_getattro) 162 163 /* Do attribute assignment for an attribute. 164 165 This macro is used in base class implementations of tp_setattro to 166 set attributes that are not managed by the base type directly. The 167 macro is generally used to assign attributes after other attribute 168 attempts to assign attributes have failed. 169 */ 170 #define PyEC_SetAttr(SELF,NAME,V) (ECBaseType->tp_setattro(SELF, NAME, V)) 171 172 173 /* Convert a method list to a method chain. */ 174 #define METHOD_CHAIN(DEF) (traverseproc)(DEF) 175 176 /* The following macro checks whether a type is an extension class: */ 177 #define PyExtensionClass_Check(TYPE) \ 178 PyObject_TypeCheck((PyObject*)(TYPE), ECExtensionClassType) 179 180 /* The following macro checks whether an instance is an extension instance: */ 181 #define PyExtensionInstance_Check(INST) \ 182 PyObject_TypeCheck(Py_TYPE(INST), ECExtensionClassType) 183 184 #define CHECK_FOR_ERRORS(MESS) 185 186 /* The following macro can be used to define an extension base class 187 that only provides method and that is used as a pure mix-in class. */ 188 #define PURE_MIXIN_CLASS(NAME,DOC,METHODS) \ 189 static PyExtensionClass NAME ## Type = { PyVarObject_HEAD_INIT(NULL, 0) # NAME, \ 190 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 191 0 , DOC, (traverseproc)METHODS, } 192 193 /* The following macros provide limited access to extension-class 194 method facilities. */ 195 196 /* Test for an ExtensionClass method: */ 197 #define PyECMethod_Check(O) PyMethod_Check((O)) 198 199 /* Create a method object that wraps a callable object and an 200 instance. Note that if the callable object is an extension class 201 method, then the new method will wrap the callable object that is 202 wrapped by the extension class method. Also note that if the 203 callable object is an extension class method with a reference 204 count of 1, then the callable object will be rebound to the 205 instance and returned with an incremented reference count. 206 */ 207 #define PyECMethod_New(CALLABLE, INST) \ 208 PyExtensionClassCAPI->PyECMethod_New_((CALLABLE),(INST)) 209 210 /* Return the instance that is bound by an extension class method. */ 211 #define PyECMethod_Self(M) (PyMethod_Check((M)) ? PyMethod_GET_SELF(M) : NULL) 212 213 /* Check whether an object has an __of__ method for returning itself 214 in the context of it's container. */ 215 #define has__of__(O) (PyExtensionInstance_Check(O) && Py_TYPE(O)->tp_descr_get != NULL) 216 217 /* The following macros are used to check whether an instance 218 or a class' instanses have instance dictionaries: */ 219 #define HasInstDict(O) (_PyObject_GetDictPtr(O) != NULL) 220 221 #define ClassHasInstDict(C) ((C)->tp_dictoffset > 0) 222 223 /* Get an object's instance dictionary. Use with caution */ 224 #define INSTANCE_DICT(inst) (_PyObject_GetDictPtr(O)) 225 226 /* Test whether an ExtensionClass, S, is a subclass of ExtensionClass C. */ 227 #define ExtensionClassSubclass_Check(S,C) PyType_IsSubtype((S), (C)) 228 229 /* Test whether an ExtensionClass instance , I, is a subclass of 230 ExtensionClass C. */ 231 #define ExtensionClassSubclassInstance_Check(I,C) PyObject_TypeCheck((I), (C)) 232 233 234 /* Export an Extension Base class in a given module dictionary with a 235 given name and ExtensionClass structure. 236 */ 237 238 #define PyExtensionClass_Export(D,N,T) \ 239 if (! ExtensionClassImported || \ 240 PyExtensionClassCAPI->PyExtensionClass_Export_((D),(N),&(T)) < 0) return NULL; 241 242 243 #define ExtensionClassImported \ 244 ((PyExtensionClassCAPI != NULL) || \ 245 (PyExtensionClassCAPI = PyCapsule_Import("ExtensionClass.CAPI2", 0))) 246 247 #endif /* EXTENSIONCLASS_H */ 248