Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
f6c1aff1
Commit
f6c1aff1
authored
Feb 17, 1997
by
Jim Fulton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Many changes in access to CAPI.
parent
72f736c7
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
522 additions
and
142 deletions
+522
-142
lib/Components/ExtensionClass/ExtensionClass.h
lib/Components/ExtensionClass/ExtensionClass.h
+261
-71
lib/Components/ExtensionClass/src/ExtensionClass.h
lib/Components/ExtensionClass/src/ExtensionClass.h
+261
-71
No files found.
lib/Components/ExtensionClass/ExtensionClass.h
View file @
f6c1aff1
/*
/*
$Id: ExtensionClass.h,v 1.
3 1996/12/06 17:13:17
jim Exp $
$Id: ExtensionClass.h,v 1.
4 1997/02/17 16:26:59
jim Exp $
Extension Class Definitions
Extension Class Definitions
...
@@ -46,6 +46,63 @@
...
@@ -46,6 +46,63 @@
damages, so the above limitation or exclusion may not apply to
damages, so the above limitation or exclusion may not apply to
you.
you.
Implementing base extension classes
A base extension class is implemented in much the same way that an
extension type is implemented, except:
- The include file, 'ExtensionClass.h', must be included.
- The type structure is declared to be of type
'PyExtensionClass', rather than of type 'PyTypeObject'.
- The type structure has an additional member that must be defined
after the documentation string. This extra member is a method chain
('PyMethodChain') containing a linked list of method definition
('PyMethodDef') lists. Method chains can be used to implement
method inheritance in C. Most extensions don't use method chains,
but simply define method lists, which are null-terminated arrays
of method definitions. A macro, 'METHOD_CHAIN' is defined in
'ExtensionClass.h' that converts a method list to a method chain.
(See the example below.)
- Module functions that create new instances must be replaced by an
'__init__' method that initializes, but does not create storage for
instances.
- The extension class must be initialized and exported to the module
with::
PyExtensionClass_Export(d,"name",type);
where 'name' is the module name and 'type' is the extension class
type object.
Attribute lookup
Attribute lookup is performed by calling the base extension class
'getattr' operation for the base extension class that includes C
data, or for the first base extension class, if none of the base
extension classes include C data. 'ExtensionClass.h' defines a
macro 'Py_FindAttrString' that can be used to find an object's
attributes that are stored in the object's instance dictionary or
in the object's class or base classes::
v = Py_FindAttrString(self,name);
In addition, a macro is provided that replaces 'Py_FindMethod'
calls with logic to perform the same sort of lookup that is
provided by 'Py_FindAttrString'.
Linking
The extension class mechanism was designed to be useful with
dynamically linked extension modules. Modules that implement
extension classes do not have to be linked against an extension
class library. The macro 'PyExtensionClass_Export' imports the
'ExtensionClass' module and uses objects imported from this module
to initialize an extension class with necessary behavior.
If you have questions regarding this software,
If you have questions regarding this software,
contact:
contact:
...
@@ -56,6 +113,9 @@
...
@@ -56,6 +113,9 @@
$Log: ExtensionClass.h,v $
$Log: ExtensionClass.h,v $
Revision 1.4 1997/02/17 16:26:59 jim
Many changes in access to CAPI.
Revision 1.3 1996/12/06 17:13:17 jim
Revision 1.3 1996/12/06 17:13:17 jim
Added support for attro functions and made use of cobject to export C
Added support for attro functions and made use of cobject to export C
interfaces.
interfaces.
...
@@ -77,11 +137,6 @@
...
@@ -77,11 +137,6 @@
/* Declarations for objects of type ExtensionClass */
/* Declarations for objects of type ExtensionClass */
#if PYTHON_API_VERSION < 1005
typedef
long
getattrofunc
;
typedef
long
setattrofunc
;
#endif
typedef
struct
{
typedef
struct
{
PyObject_VAR_HEAD
PyObject_VAR_HEAD
char
*
tp_name
;
/* For printing */
char
*
tp_name
;
/* For printing */
...
@@ -115,14 +170,6 @@ typedef struct {
...
@@ -115,14 +170,6 @@ typedef struct {
char
*
tp_doc
;
/* Documentation string */
char
*
tp_doc
;
/* Documentation string */
/* Here's the juicy stuff */
PyMethodChain
methods
;
PyObject
*
class_dictionary
;
PyObject
*
bases
;
long
class_flags
;
#define EXTENSIONCLASS_DYNAMIC_FLAG 1
#define EXTENSIONCLASS_BINDABLE_FLAG 2
#ifdef COUNT_ALLOCS
#ifdef COUNT_ALLOCS
/* these must be last */
/* these must be last */
int
tp_alloc
;
int
tp_alloc
;
...
@@ -130,75 +177,134 @@ typedef struct {
...
@@ -130,75 +177,134 @@ typedef struct {
int
tp_maxalloc
;
int
tp_maxalloc
;
struct
_typeobject
*
tp_next
;
struct
_typeobject
*
tp_next
;
#endif
#endif
/* Here's the juicy stuff: */
/* Put your method chain here. If you just have a method
list, you can use the METHON_CHAIN macro to make a chain.
*/
PyMethodChain
methods
;
/* You may set certain flags here. Only two flags are
defined at this point, the first of which is not currently
used.
*/
long
class_flags
;
#define EXTENSIONCLASS_DYNAMIC_FLAG 1
#define EXTENSIONCLASS_BINDABLE_FLAG 2
/* This is the class dictionary, which is normally created for you.
If you wish, you can provide your own class dictionary object.
If you do provide your own class dictionary, it *must* be
a mapping object. If the object given is also an extension
instance, then sub-class instance dictionaries will be created
by calling the class dictionary's class with zero argumemts.
Otherwise, subclass dictionaries will be of the default type.
*/
PyObject
*
class_dictionary
;
/* You should not set the remaining members. */
PyObject
*
bases
;
PyObject
*
reserved
;
}
PyExtensionClass
;
}
PyExtensionClass
;
#ifdef Py_COBJECT_H
/* Following are macros that are needed or useful for defining extension
PyObject
*
(
*
PyEC_getattrs
)(
PyObject
*
,
char
*
)
=
NULL
;
classes:
PyObject
*
(
*
PyEC_getattro
)(
PyObject
*
,
PyObject
*
)
=
NULL
;
*/
int
(
*
PyEC_setattrs
)(
PyObject
*
,
char
*
,
PyObject
*
)
=
NULL
;
int
(
*
PyEC_setattro
)(
PyObject
*
,
PyObject
*
,
PyObject
*
)
=
NULL
;
/* This macro redefines Py_FindMethod to do attribute for an attribute
name given by a C string lookup using extension class meta-data.
#define Py_FindMethod(M,SELF,NAME) PyEC_getattrs((SELF),(NAME))
This is used by older getattr implementations.
#define Py_FindAttrString(SELF,NAME) PyEC_getattrs((SELF),(NAME))
This macro is used in base class implementations of tp_getattr to
#define Py_FindAttr(SELF,NAME) PyEC_getattro((SELF),(NAME))
lookup methods or attributes that are not managed by the base type
#define PyEC_SetAttrString(SELF,NAME,V) PyEC_setattrs((SELF),(NAME),(V))
directly. The macro is generally used to search for attributes
#define PyEC_SetAttr(SELF,NAME,V) PyEC_setattro((SELF),(NAME),(V))
after other attribute searches have failed.
#define IMPORT_C_OBJECT(P,C,M) { \
Note that in Python 1.4, a getattr operation may be provided that
PyObject *_IMPORT_C_OBJECT; \
uses an object argument. Classes that support this new operation
if((_IMPORT_C_OBJECT=PyObject_GetAttrString(M,#P))) { \
should use Py_FindAttr.
C=PyCObject_AsVoidPtr(_IMPORT_C_OBJECT); \
*/
Py_DECREF(_IMPORT_C_OBJECT); }}
#define PyExtensionClass_Export(D,N,T) { \
PyObject *_ExtensionClass_module, *_ExtensionClass_spam; \
if((_ExtensionClass_module=PyImport_ImportModule("ExtensionClass"))) { \
if(_ExtensionClass_spam= \
PyObject_CallMethod(_ExtensionClass_module, \
"ExtensionClassType", "Oi", &T, 42)) { \
Py_DECREF(_ExtensionClass_spam); \
PyMapping_SetItemString(D,N,(PyObject*)&T); } \
IMPORT_C_OBJECT(_PyEC_getattrs,PyEC_getattrs,_ExtensionClass_module) \
IMPORT_C_OBJECT(_PyEC_getattro,PyEC_getattro,_ExtensionClass_module) \
IMPORT_C_OBJECT(_PyEC_setattrs,PyEC_setattrs,_ExtensionClass_module) \
IMPORT_C_OBJECT(_PyEC_setattro,PyEC_setattro,_ExtensionClass_module) \
Py_DECREF(_ExtensionClass_module); }}
#else
/* Don't look at this. :-) */
#define Py_FindMethod(M,SELF,NAME) \
#define Py_FindMethod(M,SELF,NAME) \
((getattrfunc)((SELF)->ob_type->ob_type->tp_getattr((SELF)->ob_type,"."))) \
(PyExtensionClassCAPI->getattrs((SELF),(NAME)))
((SELF),(NAME))
/* Do method or attribute lookup for an attribute name given by a C
string using extension class meta-data.
This macro is used in base class implementations of tp_getattro to
lookup methods or attributes that are not managed by the base type
directly. The macro is generally used to search for attributes
after other attribute searches have failed.
Note that in Python 1.4, a getattr operation may be provided that
uses an object argument. Classes that support this new operation
should use Py_FindAttr.
*/
#define Py_FindAttrString(SELF,NAME) \
#define Py_FindAttrString(SELF,NAME) \
((getattrfunc)((SELF)->ob_type->ob_type->tp_getattr((SELF)->ob_type,"."))) \
(PyExtensionClassCAPI->getattrs((SELF),(NAME)))
((SELF),(NAME) )
#define PyEC_SetAttrString(SELF,NAME,V) \
/* Do method or attribute lookup using extension class meta-data.
((setattrfunc)((SELF)->ob_type->ob_type->tp_getattr((SELF)->ob_type, \
".s"))) \
((SELF),(NAME),(V))
#define PyExtensionClass_Export(D,N,T) { \
PyObject *_ExtensionClass_module; \
if((_ExtensionClass_module=PyImport_ImportModule("ExtensionClass"))) { \
if(PyObject_CallMethod(_ExtensionClass_module, \
"ExtensionClassType", "Oi", &T, 42)) \
PyMapping_SetItemString(D,N,(PyObject*)&T); \
Py_DECREF(_ExtensionClass_module); \
} \
}
#endif
This macro is used in base class implementations of tp_getattr to
lookup methods or attributes that are not managed by the base type
directly. The macro is generally used to search for attributes
after other attribute searches have failed. */
#define Py_FindAttr(SELF,NAME) (PyExtensionClassCAPI->getattro((SELF),(NAME)))
/* Do method or attribute assignment for an attribute name given by a
C string using extension class meta-data.
This macro is used in base class implementations of tp_setattr to
set attributes that are not managed by the base type directly. The
macro is generally used to assign attributes after other attribute
attempts to assign attributes have failed.
Note that in Python 1.4, a setattr operation may be provided that
uses an object argument. Classes that support this new operation
should use PyEC_SetAttr.
*/
#define PyEC_SetAttrString(SELF,NAME,V) \
(PyExtensionClassCAPI->setattrs((SELF),(NAME),(V)))
/* Do attribute assignment for an attribute.
This macro is used in base class implementations of tp_setattro to
set attributes that are not managed by the base type directly. The
macro is generally used to assign attributes after other attribute
attempts to assign attributes have failed.
*/
#define PyEC_SetAttr(SELF,NAME,V) \
(PyExtensionClassCAPI->setattro((SELF),(NAME),(V)))
/* Export an Extension Base class in a given module dictionary with a
given name and ExtensionClass structure.
*/
#define PyExtensionClass_Export(D,N,T) \
if(PyExtensionClassCAPI || \
(PyExtensionClassCAPI= PyCObject_Import("ExtensionClass","CAPI"))) \
{ PyExtensionClassCAPI->Export(D,N,&T); }
/* Convert a method list to a method chain. */
#define METHOD_CHAIN(DEF) { DEF, NULL }
#define METHOD_CHAIN(DEF) { DEF, NULL }
/* The following macro checks whether a type is an extension class: */
#define PyExtensionClass_Check(TYPE) \
((PyObject*)(TYPE)->ob_type==PyExtensionClassCAPI->ExtensionClassType)
/* The following macro checks whether an instance is an extension instance: */
#define PyExtensionInstance_Check(INST) \
((PyObject*)(INST)->ob_type->ob_type== \
PyExtensionClassCAPI->ExtensionClassType)
/* The following macro checks for errors and prints out an error
message that is more informative than the one given by Python when
an extension module initialization fails.
*/
#define CHECK_FOR_ERRORS(MESS) \
#define CHECK_FOR_ERRORS(MESS) \
if(PyErr_Occurred()) { \
if(PyErr_Occurred()) { \
PyObject *__sys_exc_type, *__sys_exc_value, *__sys_exc_traceback; \
PyObject *__sys_exc_type, *__sys_exc_value, *__sys_exc_traceback; \
PyErr_Fetch( &__sys_exc_type, &__sys_exc_value, &__sys_exc_traceback); \
PyErr_Fetch( &__sys_exc_type, &__sys_exc_value, \
&__sys_exc_traceback); \
fprintf(stderr, # MESS ":\n\t"); \
fprintf(stderr, # MESS ":\n\t"); \
PyObject_Print(__sys_exc_type, stderr,0); \
PyObject_Print(__sys_exc_type, stderr,0); \
fprintf(stderr,", "); \
fprintf(stderr,", "); \
...
@@ -208,6 +314,90 @@ if(PyErr_Occurred()) { \
...
@@ -208,6 +314,90 @@ if(PyErr_Occurred()) { \
Py_FatalError(# MESS); \
Py_FatalError(# MESS); \
}
}
/* The following macro can be used to define an extension base class
that only provides method and that is used as a pure mix-in class. */
#define PURE_MIXIN_CLASS(NAME,DOC,METHODS) \
static PyExtensionClass NAME ## Type = { PyObject_HEAD_INIT(NULL) \
0, # NAME, sizeof(PyPureMixinObject), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, DOC, {METHODS, NULL}};
/* The following macros provide limited access to extension-class
method facilities. */
/* Test for an ExtensionClass method: */
#define PyECMethod_Check(O) \
((PyObject*)(O)->ob_type==PyExtensionClassCAPI->MethodType)
/* Create a method object that wraps a callable object and an
instance. Note that if the callable object is an extension class
method, then the new method will wrap the callable object that is
wrapped by the extension class method. Also note that if the
callable object is an extension class method with a reference
count of 1, then the callable object will be rebound to the
instance and returned with an incremented reference count.
*/
#define PyECMethod_New(CALLABLE,INST) \
(PyExtensionClassCAPI->Method_New(CALLABLE,INST))
/* Return the instance that is bound by an extension class method. */
#define PyECMethod_Self(M) (((PyECMethodObject*)M)->self)
/* Check whether an object has an __of__ method for returning itself
in the context of it's container. */
#define has__of__(O) \
((O)->ob_type->ob_type == \
(PyTypeObject*)PyExtensionClassCAPI->ExtensionClassType && \
(((PyExtensionClass*)((O)->ob_type))->class_flags & \
EXTENSIONCLASS_BINDABLE_FLAG))
/*****************************************************************************
WARNING: EVERYTHING BELOW HERE IS PRIVATE TO THE EXTENSION CLASS INTERFACE
IMPLEMENTATION AND IS SUBJECT TO CHANGE !!!
*****************************************************************************/
static
struct
ExtensionClassCAPIstruct
{
int
(
*
Export
)(
PyObject
*
dict
,
char
*
name
,
PyExtensionClass
*
ob_type
);
PyObject
*
(
*
getattrs
)(
PyObject
*
,
char
*
);
PyObject
*
(
*
getattro
)(
PyObject
*
,
PyObject
*
);
int
(
*
setattrs
)(
PyObject
*
,
char
*
,
PyObject
*
);
int
(
*
setattro
)(
PyObject
*
,
PyObject
*
,
PyObject
*
);
PyObject
*
ExtensionClassType
;
PyObject
*
MethodType
;
PyObject
*
(
*
Method_New
)(
PyObject
*
callable
,
PyObject
*
inst
);
}
*
PyExtensionClassCAPI
=
NULL
;
typedef
struct
{
PyObject_HEAD
}
PyPureMixinObject
;
typedef
struct
{
PyObject_HEAD
PyTypeObject
*
type
;
PyObject
*
self
;
PyObject
*
meth
;
}
PyECMethodObject
;
static
void
*
PyCObject_Import
(
char
*
module_name
,
char
*
name
)
{
PyObject
*
m
,
*
c
;
void
*
r
=
NULL
;
if
(
m
=
PyImport_ImportModule
(
module_name
))
{
if
(
c
=
PyObject_GetAttrString
(
m
,
name
))
{
r
=
PyCObject_AsVoidPtr
(
c
);
Py_DECREF
(
c
);
}
Py_DECREF
(
m
);
}
return
r
;
}
#endif
#endif
lib/Components/ExtensionClass/src/ExtensionClass.h
View file @
f6c1aff1
/*
/*
$Id: ExtensionClass.h,v 1.
3 1996/12/06 17:13:17
jim Exp $
$Id: ExtensionClass.h,v 1.
4 1997/02/17 16:26:59
jim Exp $
Extension Class Definitions
Extension Class Definitions
...
@@ -46,6 +46,63 @@
...
@@ -46,6 +46,63 @@
damages, so the above limitation or exclusion may not apply to
damages, so the above limitation or exclusion may not apply to
you.
you.
Implementing base extension classes
A base extension class is implemented in much the same way that an
extension type is implemented, except:
- The include file, 'ExtensionClass.h', must be included.
- The type structure is declared to be of type
'PyExtensionClass', rather than of type 'PyTypeObject'.
- The type structure has an additional member that must be defined
after the documentation string. This extra member is a method chain
('PyMethodChain') containing a linked list of method definition
('PyMethodDef') lists. Method chains can be used to implement
method inheritance in C. Most extensions don't use method chains,
but simply define method lists, which are null-terminated arrays
of method definitions. A macro, 'METHOD_CHAIN' is defined in
'ExtensionClass.h' that converts a method list to a method chain.
(See the example below.)
- Module functions that create new instances must be replaced by an
'__init__' method that initializes, but does not create storage for
instances.
- The extension class must be initialized and exported to the module
with::
PyExtensionClass_Export(d,"name",type);
where 'name' is the module name and 'type' is the extension class
type object.
Attribute lookup
Attribute lookup is performed by calling the base extension class
'getattr' operation for the base extension class that includes C
data, or for the first base extension class, if none of the base
extension classes include C data. 'ExtensionClass.h' defines a
macro 'Py_FindAttrString' that can be used to find an object's
attributes that are stored in the object's instance dictionary or
in the object's class or base classes::
v = Py_FindAttrString(self,name);
In addition, a macro is provided that replaces 'Py_FindMethod'
calls with logic to perform the same sort of lookup that is
provided by 'Py_FindAttrString'.
Linking
The extension class mechanism was designed to be useful with
dynamically linked extension modules. Modules that implement
extension classes do not have to be linked against an extension
class library. The macro 'PyExtensionClass_Export' imports the
'ExtensionClass' module and uses objects imported from this module
to initialize an extension class with necessary behavior.
If you have questions regarding this software,
If you have questions regarding this software,
contact:
contact:
...
@@ -56,6 +113,9 @@
...
@@ -56,6 +113,9 @@
$Log: ExtensionClass.h,v $
$Log: ExtensionClass.h,v $
Revision 1.4 1997/02/17 16:26:59 jim
Many changes in access to CAPI.
Revision 1.3 1996/12/06 17:13:17 jim
Revision 1.3 1996/12/06 17:13:17 jim
Added support for attro functions and made use of cobject to export C
Added support for attro functions and made use of cobject to export C
interfaces.
interfaces.
...
@@ -77,11 +137,6 @@
...
@@ -77,11 +137,6 @@
/* Declarations for objects of type ExtensionClass */
/* Declarations for objects of type ExtensionClass */
#if PYTHON_API_VERSION < 1005
typedef
long
getattrofunc
;
typedef
long
setattrofunc
;
#endif
typedef
struct
{
typedef
struct
{
PyObject_VAR_HEAD
PyObject_VAR_HEAD
char
*
tp_name
;
/* For printing */
char
*
tp_name
;
/* For printing */
...
@@ -115,14 +170,6 @@ typedef struct {
...
@@ -115,14 +170,6 @@ typedef struct {
char
*
tp_doc
;
/* Documentation string */
char
*
tp_doc
;
/* Documentation string */
/* Here's the juicy stuff */
PyMethodChain
methods
;
PyObject
*
class_dictionary
;
PyObject
*
bases
;
long
class_flags
;
#define EXTENSIONCLASS_DYNAMIC_FLAG 1
#define EXTENSIONCLASS_BINDABLE_FLAG 2
#ifdef COUNT_ALLOCS
#ifdef COUNT_ALLOCS
/* these must be last */
/* these must be last */
int
tp_alloc
;
int
tp_alloc
;
...
@@ -130,75 +177,134 @@ typedef struct {
...
@@ -130,75 +177,134 @@ typedef struct {
int
tp_maxalloc
;
int
tp_maxalloc
;
struct
_typeobject
*
tp_next
;
struct
_typeobject
*
tp_next
;
#endif
#endif
/* Here's the juicy stuff: */
/* Put your method chain here. If you just have a method
list, you can use the METHON_CHAIN macro to make a chain.
*/
PyMethodChain
methods
;
/* You may set certain flags here. Only two flags are
defined at this point, the first of which is not currently
used.
*/
long
class_flags
;
#define EXTENSIONCLASS_DYNAMIC_FLAG 1
#define EXTENSIONCLASS_BINDABLE_FLAG 2
/* This is the class dictionary, which is normally created for you.
If you wish, you can provide your own class dictionary object.
If you do provide your own class dictionary, it *must* be
a mapping object. If the object given is also an extension
instance, then sub-class instance dictionaries will be created
by calling the class dictionary's class with zero argumemts.
Otherwise, subclass dictionaries will be of the default type.
*/
PyObject
*
class_dictionary
;
/* You should not set the remaining members. */
PyObject
*
bases
;
PyObject
*
reserved
;
}
PyExtensionClass
;
}
PyExtensionClass
;
#ifdef Py_COBJECT_H
/* Following are macros that are needed or useful for defining extension
PyObject
*
(
*
PyEC_getattrs
)(
PyObject
*
,
char
*
)
=
NULL
;
classes:
PyObject
*
(
*
PyEC_getattro
)(
PyObject
*
,
PyObject
*
)
=
NULL
;
*/
int
(
*
PyEC_setattrs
)(
PyObject
*
,
char
*
,
PyObject
*
)
=
NULL
;
int
(
*
PyEC_setattro
)(
PyObject
*
,
PyObject
*
,
PyObject
*
)
=
NULL
;
/* This macro redefines Py_FindMethod to do attribute for an attribute
name given by a C string lookup using extension class meta-data.
#define Py_FindMethod(M,SELF,NAME) PyEC_getattrs((SELF),(NAME))
This is used by older getattr implementations.
#define Py_FindAttrString(SELF,NAME) PyEC_getattrs((SELF),(NAME))
This macro is used in base class implementations of tp_getattr to
#define Py_FindAttr(SELF,NAME) PyEC_getattro((SELF),(NAME))
lookup methods or attributes that are not managed by the base type
#define PyEC_SetAttrString(SELF,NAME,V) PyEC_setattrs((SELF),(NAME),(V))
directly. The macro is generally used to search for attributes
#define PyEC_SetAttr(SELF,NAME,V) PyEC_setattro((SELF),(NAME),(V))
after other attribute searches have failed.
#define IMPORT_C_OBJECT(P,C,M) { \
Note that in Python 1.4, a getattr operation may be provided that
PyObject *_IMPORT_C_OBJECT; \
uses an object argument. Classes that support this new operation
if((_IMPORT_C_OBJECT=PyObject_GetAttrString(M,#P))) { \
should use Py_FindAttr.
C=PyCObject_AsVoidPtr(_IMPORT_C_OBJECT); \
*/
Py_DECREF(_IMPORT_C_OBJECT); }}
#define PyExtensionClass_Export(D,N,T) { \
PyObject *_ExtensionClass_module, *_ExtensionClass_spam; \
if((_ExtensionClass_module=PyImport_ImportModule("ExtensionClass"))) { \
if(_ExtensionClass_spam= \
PyObject_CallMethod(_ExtensionClass_module, \
"ExtensionClassType", "Oi", &T, 42)) { \
Py_DECREF(_ExtensionClass_spam); \
PyMapping_SetItemString(D,N,(PyObject*)&T); } \
IMPORT_C_OBJECT(_PyEC_getattrs,PyEC_getattrs,_ExtensionClass_module) \
IMPORT_C_OBJECT(_PyEC_getattro,PyEC_getattro,_ExtensionClass_module) \
IMPORT_C_OBJECT(_PyEC_setattrs,PyEC_setattrs,_ExtensionClass_module) \
IMPORT_C_OBJECT(_PyEC_setattro,PyEC_setattro,_ExtensionClass_module) \
Py_DECREF(_ExtensionClass_module); }}
#else
/* Don't look at this. :-) */
#define Py_FindMethod(M,SELF,NAME) \
#define Py_FindMethod(M,SELF,NAME) \
((getattrfunc)((SELF)->ob_type->ob_type->tp_getattr((SELF)->ob_type,"."))) \
(PyExtensionClassCAPI->getattrs((SELF),(NAME)))
((SELF),(NAME))
/* Do method or attribute lookup for an attribute name given by a C
string using extension class meta-data.
This macro is used in base class implementations of tp_getattro to
lookup methods or attributes that are not managed by the base type
directly. The macro is generally used to search for attributes
after other attribute searches have failed.
Note that in Python 1.4, a getattr operation may be provided that
uses an object argument. Classes that support this new operation
should use Py_FindAttr.
*/
#define Py_FindAttrString(SELF,NAME) \
#define Py_FindAttrString(SELF,NAME) \
((getattrfunc)((SELF)->ob_type->ob_type->tp_getattr((SELF)->ob_type,"."))) \
(PyExtensionClassCAPI->getattrs((SELF),(NAME)))
((SELF),(NAME) )
#define PyEC_SetAttrString(SELF,NAME,V) \
/* Do method or attribute lookup using extension class meta-data.
((setattrfunc)((SELF)->ob_type->ob_type->tp_getattr((SELF)->ob_type, \
".s"))) \
((SELF),(NAME),(V))
#define PyExtensionClass_Export(D,N,T) { \
PyObject *_ExtensionClass_module; \
if((_ExtensionClass_module=PyImport_ImportModule("ExtensionClass"))) { \
if(PyObject_CallMethod(_ExtensionClass_module, \
"ExtensionClassType", "Oi", &T, 42)) \
PyMapping_SetItemString(D,N,(PyObject*)&T); \
Py_DECREF(_ExtensionClass_module); \
} \
}
#endif
This macro is used in base class implementations of tp_getattr to
lookup methods or attributes that are not managed by the base type
directly. The macro is generally used to search for attributes
after other attribute searches have failed. */
#define Py_FindAttr(SELF,NAME) (PyExtensionClassCAPI->getattro((SELF),(NAME)))
/* Do method or attribute assignment for an attribute name given by a
C string using extension class meta-data.
This macro is used in base class implementations of tp_setattr to
set attributes that are not managed by the base type directly. The
macro is generally used to assign attributes after other attribute
attempts to assign attributes have failed.
Note that in Python 1.4, a setattr operation may be provided that
uses an object argument. Classes that support this new operation
should use PyEC_SetAttr.
*/
#define PyEC_SetAttrString(SELF,NAME,V) \
(PyExtensionClassCAPI->setattrs((SELF),(NAME),(V)))
/* Do attribute assignment for an attribute.
This macro is used in base class implementations of tp_setattro to
set attributes that are not managed by the base type directly. The
macro is generally used to assign attributes after other attribute
attempts to assign attributes have failed.
*/
#define PyEC_SetAttr(SELF,NAME,V) \
(PyExtensionClassCAPI->setattro((SELF),(NAME),(V)))
/* Export an Extension Base class in a given module dictionary with a
given name and ExtensionClass structure.
*/
#define PyExtensionClass_Export(D,N,T) \
if(PyExtensionClassCAPI || \
(PyExtensionClassCAPI= PyCObject_Import("ExtensionClass","CAPI"))) \
{ PyExtensionClassCAPI->Export(D,N,&T); }
/* Convert a method list to a method chain. */
#define METHOD_CHAIN(DEF) { DEF, NULL }
#define METHOD_CHAIN(DEF) { DEF, NULL }
/* The following macro checks whether a type is an extension class: */
#define PyExtensionClass_Check(TYPE) \
((PyObject*)(TYPE)->ob_type==PyExtensionClassCAPI->ExtensionClassType)
/* The following macro checks whether an instance is an extension instance: */
#define PyExtensionInstance_Check(INST) \
((PyObject*)(INST)->ob_type->ob_type== \
PyExtensionClassCAPI->ExtensionClassType)
/* The following macro checks for errors and prints out an error
message that is more informative than the one given by Python when
an extension module initialization fails.
*/
#define CHECK_FOR_ERRORS(MESS) \
#define CHECK_FOR_ERRORS(MESS) \
if(PyErr_Occurred()) { \
if(PyErr_Occurred()) { \
PyObject *__sys_exc_type, *__sys_exc_value, *__sys_exc_traceback; \
PyObject *__sys_exc_type, *__sys_exc_value, *__sys_exc_traceback; \
PyErr_Fetch( &__sys_exc_type, &__sys_exc_value, &__sys_exc_traceback); \
PyErr_Fetch( &__sys_exc_type, &__sys_exc_value, \
&__sys_exc_traceback); \
fprintf(stderr, # MESS ":\n\t"); \
fprintf(stderr, # MESS ":\n\t"); \
PyObject_Print(__sys_exc_type, stderr,0); \
PyObject_Print(__sys_exc_type, stderr,0); \
fprintf(stderr,", "); \
fprintf(stderr,", "); \
...
@@ -208,6 +314,90 @@ if(PyErr_Occurred()) { \
...
@@ -208,6 +314,90 @@ if(PyErr_Occurred()) { \
Py_FatalError(# MESS); \
Py_FatalError(# MESS); \
}
}
/* The following macro can be used to define an extension base class
that only provides method and that is used as a pure mix-in class. */
#define PURE_MIXIN_CLASS(NAME,DOC,METHODS) \
static PyExtensionClass NAME ## Type = { PyObject_HEAD_INIT(NULL) \
0, # NAME, sizeof(PyPureMixinObject), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, DOC, {METHODS, NULL}};
/* The following macros provide limited access to extension-class
method facilities. */
/* Test for an ExtensionClass method: */
#define PyECMethod_Check(O) \
((PyObject*)(O)->ob_type==PyExtensionClassCAPI->MethodType)
/* Create a method object that wraps a callable object and an
instance. Note that if the callable object is an extension class
method, then the new method will wrap the callable object that is
wrapped by the extension class method. Also note that if the
callable object is an extension class method with a reference
count of 1, then the callable object will be rebound to the
instance and returned with an incremented reference count.
*/
#define PyECMethod_New(CALLABLE,INST) \
(PyExtensionClassCAPI->Method_New(CALLABLE,INST))
/* Return the instance that is bound by an extension class method. */
#define PyECMethod_Self(M) (((PyECMethodObject*)M)->self)
/* Check whether an object has an __of__ method for returning itself
in the context of it's container. */
#define has__of__(O) \
((O)->ob_type->ob_type == \
(PyTypeObject*)PyExtensionClassCAPI->ExtensionClassType && \
(((PyExtensionClass*)((O)->ob_type))->class_flags & \
EXTENSIONCLASS_BINDABLE_FLAG))
/*****************************************************************************
WARNING: EVERYTHING BELOW HERE IS PRIVATE TO THE EXTENSION CLASS INTERFACE
IMPLEMENTATION AND IS SUBJECT TO CHANGE !!!
*****************************************************************************/
static
struct
ExtensionClassCAPIstruct
{
int
(
*
Export
)(
PyObject
*
dict
,
char
*
name
,
PyExtensionClass
*
ob_type
);
PyObject
*
(
*
getattrs
)(
PyObject
*
,
char
*
);
PyObject
*
(
*
getattro
)(
PyObject
*
,
PyObject
*
);
int
(
*
setattrs
)(
PyObject
*
,
char
*
,
PyObject
*
);
int
(
*
setattro
)(
PyObject
*
,
PyObject
*
,
PyObject
*
);
PyObject
*
ExtensionClassType
;
PyObject
*
MethodType
;
PyObject
*
(
*
Method_New
)(
PyObject
*
callable
,
PyObject
*
inst
);
}
*
PyExtensionClassCAPI
=
NULL
;
typedef
struct
{
PyObject_HEAD
}
PyPureMixinObject
;
typedef
struct
{
PyObject_HEAD
PyTypeObject
*
type
;
PyObject
*
self
;
PyObject
*
meth
;
}
PyECMethodObject
;
static
void
*
PyCObject_Import
(
char
*
module_name
,
char
*
name
)
{
PyObject
*
m
,
*
c
;
void
*
r
=
NULL
;
if
(
m
=
PyImport_ImportModule
(
module_name
))
{
if
(
c
=
PyObject_GetAttrString
(
m
,
name
))
{
r
=
PyCObject_AsVoidPtr
(
c
);
Py_DECREF
(
c
);
}
Py_DECREF
(
m
);
}
return
r
;
}
#endif
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment