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
959a884e
Commit
959a884e
authored
Feb 17, 1997
by
Jim Fulton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Many changes.
parent
f6c1aff1
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
1594 additions
and
1406 deletions
+1594
-1406
lib/Components/ExtensionClass/ExtensionClass.c
lib/Components/ExtensionClass/ExtensionClass.c
+797
-703
lib/Components/ExtensionClass/src/ExtensionClass.c
lib/Components/ExtensionClass/src/ExtensionClass.c
+797
-703
No files found.
lib/Components/ExtensionClass/ExtensionClass.c
View file @
959a884e
/*
$Id: ExtensionClass.c,v 1.
4 1996/12/06 17:12:29
jim Exp $
$Id: ExtensionClass.c,v 1.
5 1997/02/17 16:27:53
jim Exp $
Extension Class
...
...
@@ -56,6 +56,9 @@
(540) 371-6909
$Log: ExtensionClass.c,v $
Revision 1.5 1997/02/17 16:27:53 jim
Many changes.
Revision 1.4 1996/12/06 17:12:29 jim
Major speed enhancements for attribute lookup and calling special
methods.
...
...
@@ -88,40 +91,56 @@ static char ExtensionClass_module_documentation[] =
" - They provide access to unbound methods,
\n
"
" - They can be called to create instances.
\n
"
"
\n
"
"$Id: ExtensionClass.c,v 1.
4 1996/12/06 17:12:29
jim Exp $
\n
"
"$Id: ExtensionClass.c,v 1.
5 1997/02/17 16:27:53
jim Exp $
\n
"
;
#include <stdio.h>
#include "Python.h"
#include "PyErr_Format.c"
static
void
PyVar_Assign
(
PyObject
**
v
,
PyObject
*
e
)
{
Py_XDECREF
(
*
v
);
*
v
=
e
;
}
#define ASSIGN(V,E)
{PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define ASSIGN(V,E)
PyVar_Assign(&(V),(E))
#define UNLESS(E) if(!(E))
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E) UNLESS(V)
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E)
;
UNLESS(V)
#define INSTANCE_DICT(inst) \
*(((PyObject**)inst) + (inst->ob_type->tp_basicsize/sizeof(PyObject*) - 1))
typedef
struct
{
PyObject_HEAD
}
Dataless
;
/* Declarations for objects of type ExtensionClass */
#include "ExtensionClass.h"
staticforward
PyExtensionClass
CCLtype
;
#define PyExtensionClass_Check(O) ((O)->ob_type == (PyTypeObject*)&CCLtype)
#define PyExtensionInstance_Check(O) \
((O)->ob_type->ob_type == (PyTypeObject*)&CCLtype)
#define AsPyExtensionClass(O) ((PyExtensionClass*)(O))
#define PyExtensionClassOf(O) ((PyExtensionClass*)((O)->ob_type))
staticforward
PyExtensionClass
ECType
;
#define ExtensionClass_Check(O) ((O)->ob_type == (PyTypeObject*)&ECType)
#define ExtensionInstance_Check(O) \
((O)->ob_type->ob_type == (PyTypeObject*)&ECType)
#define AsExtensionClass(O) ((PyExtensionClass*)(O))
#define ExtensionClassOf(O) ((PyExtensionClass*)((O)->ob_type))
#define AsPyObject(O) ((PyObject*)(O))
#define NeedsToBeBound(O) \
((O)->ob_type->ob_type == (PyTypeObject*)&ECType && \
(((PyExtensionClass*)((O)->ob_type))->class_flags & \
EXTENSIONCLASS_BINDABLE_FLAG))
static
PyObject
*
py__add__
,
*
py__sub__
,
*
py__mul__
,
*
py__div__
,
*
py__mod__
,
*
py__pow__
,
*
py__divmod__
,
*
py__lshift__
,
*
py__rshift__
,
*
py__and__
,
*
py__or__
,
*
py__xor__
,
*
py__coerce__
,
*
py__neg__
,
*
py__pos__
,
*
py__abs__
,
*
py__nonzero__
,
*
py__inv__
,
*
py__int__
,
*
py__long__
,
*
py__float__
,
*
py__oct__
,
*
py__hex__
,
*
py__getitem__
,
*
py__setitem__
,
*
py__getslice__
,
*
py__setslice__
,
*
py__concat__
,
*
py__repeat__
,
*
py__len__
,
*
py__bind_to_object__
,
*
py__call__
,
*
py__getattr__
,
*
py__setattr__
,
*
py__del__
,
*
py__repr__
,
*
py__str__
,
*
py__hash__
,
*
py__cmp__
,
*
py__var_size__
,
*
py__init__
;
*
py__long__
,
*
py__float__
,
*
py__oct__
,
*
py__hex__
,
*
py__getitem__
,
*
py__setitem__
,
*
py__delitem__
,
*
py__getslice__
,
*
py__setslice__
,
*
py__delslice__
,
*
py__concat__
,
*
py__repeat__
,
*
py__len__
,
*
py__of__
,
*
py__call__
,
*
py__getattr__
,
*
py__setattr__
,
*
py__delattr__
,
*
py__del__
,
*
py__repr__
,
*
py__str__
,
*
py__class__
,
*
py__hash__
,
*
py__cmp__
,
*
py__var_size__
,
*
py__init__
,
*
py__getinitargs__
,
*
py__getstate__
,
*
py__setstate__
,
*
py__dict__
,
*
pyclass_
;
static
void
init_py_names
()
...
...
@@ -152,26 +171,48 @@ init_py_names()
INIT_PY_NAME
(
__hex__
);
INIT_PY_NAME
(
__getitem__
);
INIT_PY_NAME
(
__setitem__
);
INIT_PY_NAME
(
__delitem__
);
INIT_PY_NAME
(
__getslice__
);
INIT_PY_NAME
(
__setslice__
);
INIT_PY_NAME
(
__delslice__
);
INIT_PY_NAME
(
__concat__
);
INIT_PY_NAME
(
__repeat__
);
INIT_PY_NAME
(
__len__
);
INIT_PY_NAME
(
__
bind_to_object
__
);
INIT_PY_NAME
(
__
of
__
);
INIT_PY_NAME
(
__call__
);
INIT_PY_NAME
(
__getattr__
);
INIT_PY_NAME
(
__setattr__
);
INIT_PY_NAME
(
__delattr__
);
INIT_PY_NAME
(
__del__
);
INIT_PY_NAME
(
__repr__
);
INIT_PY_NAME
(
__str__
);
INIT_PY_NAME
(
__class__
);
INIT_PY_NAME
(
__hash__
);
INIT_PY_NAME
(
__cmp__
);
INIT_PY_NAME
(
__var_size__
);
INIT_PY_NAME
(
__init__
);
INIT_PY_NAME
(
__getinitargs__
);
INIT_PY_NAME
(
__getstate__
);
INIT_PY_NAME
(
__setstate__
);
INIT_PY_NAME
(
__dict__
);
INIT_PY_NAME
(
class_
);
#undef INIT_PY_NAME
}
static
PyObject
*
CallMethodO
(
PyObject
*
self
,
PyObject
*
name
,
PyObject
*
args
,
PyObject
*
kw
)
{
if
(
!
args
&&
PyErr_Occurred
())
return
NULL
;
UNLESS
(
name
=
PyObject_GetAttr
(
self
,
name
))
return
NULL
;
ASSIGN
(
name
,
PyEval_CallObjectWithKeywords
(
name
,
args
,
kw
));
if
(
args
)
Py_DECREF
(
args
);
return
name
;
}
#define Build Py_BuildValue
/* CMethod objects: */
typedef
struct
{
...
...
@@ -204,9 +245,9 @@ CMethod_issubclass(PyExtensionClass *sub, PyExtensionClass *type)
{
t
=
PyTuple_GET_ITEM
(
sub
->
bases
,
i
);
if
(
t
==
(
PyObject
*
)
type
)
return
1
;
if
(
Py
ExtensionClass_Check
(
t
)
&&
As
Py
ExtensionClass
(
t
)
->
bases
&&
CMethod_issubclass
(
As
Py
ExtensionClass
(
t
),
type
)
if
(
ExtensionClass_Check
(
t
)
&&
AsExtensionClass
(
t
)
->
bases
&&
CMethod_issubclass
(
AsExtensionClass
(
t
),
type
)
)
return
1
;
}
return
0
;
...
...
@@ -220,8 +261,8 @@ CMethod_issubclass(PyExtensionClass *sub, PyExtensionClass *type)
(PyExtensionClass *)(C2))
static
CMethod
*
newCMethod
(
Py
TypeObject
*
type
,
static
PyObject
*
newCMethod
(
Py
ExtensionClass
*
type
,
PyObject
*
inst
,
char
*
name
,
PyCFunction
meth
,
int
flags
,
char
*
doc
)
{
CMethod
*
self
;
...
...
@@ -229,13 +270,14 @@ newCMethod(PyTypeObject *type,
UNLESS
(
self
=
PyObject_NEW
(
CMethod
,
&
CMethodType
))
return
NULL
;
Py_INCREF
(
type
);
self
->
type
=
type
;
self
->
self
=
NULL
;
Py_XINCREF
(
inst
);
self
->
type
=
(
PyTypeObject
*
)
type
;
self
->
self
=
inst
;
self
->
name
=
name
;
self
->
meth
=
meth
;
self
->
flags
=
flags
;
self
->
doc
=
doc
;
return
self
;
return
(
PyObject
*
)
self
;
}
static
CMethod
*
...
...
@@ -244,7 +286,7 @@ bindCMethod(CMethod *m, PyObject *inst)
CMethod
*
self
;
UNLESS
(
inst
->
ob_type
==
m
->
type
||
(
Py
ExtensionInstance_Check
(
inst
)
(
ExtensionInstance_Check
(
inst
)
&&
SubclassInstance_Check
(
inst
,
m
->
type
))
)
{
...
...
@@ -268,7 +310,10 @@ bindCMethod(CMethod *m, PyObject *inst)
static
void
CMethod_dealloc
(
CMethod
*
self
)
{
Py_DECREF
(
self
->
type
);
#ifdef TRACE_DEALLOC
fprintf
(
stderr
,
"Deallocating C method %s
\n
"
,
self
->
name
);
#endif
Py_XDECREF
(
self
->
type
);
Py_XDECREF
(
self
->
self
);
PyMem_DEL
(
self
);
}
...
...
@@ -297,13 +342,10 @@ call_cmethod(CMethod *self, PyObject *inst, PyObject *args, PyObject *kw)
}
}
static
PyObject
*
CMethod_call
(
CMethod
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
int
size
;
char
*
buf
;
PyObject
*
s
;
if
(
self
->
self
)
return
call_cmethod
(
self
,
self
->
self
,
args
,
kw
);
...
...
@@ -313,29 +355,23 @@ CMethod_call(CMethod *self, PyObject *args, PyObject *kw)
UNLESS
(
first
=
PyTuple_GET_ITEM
(
args
,
0
))
return
NULL
;
if
(
first
->
ob_type
==
self
->
type
||
(
Py
ExtensionInstance_Check
(
first
)
(
ExtensionInstance_Check
(
first
)
&&
CMethod_issubclass
(
Py
ExtensionClassOf
(
first
),
As
Py
ExtensionClass
(
self
->
type
))
CMethod_issubclass
(
ExtensionClassOf
(
first
),
AsExtensionClass
(
self
->
type
))
)
);
{
PyObject
*
rest
=
0
;
UNLESS
(
rest
=
PySequence_GetSlice
(
args
,
1
,
size
))
return
NULL
;
return
call_cmethod
(
self
,
first
,
rest
,
kw
);
ASSIGN
(
rest
,
call_cmethod
(
self
,
first
,
rest
,
kw
));
return
rest
;
}
}
/* Call of unbound method without instance argument */
size
=
strlen
(
self
->
type
->
tp_name
);
UNLESS
(
s
=
PyString_FromStringAndSize
(
NULL
,
size
+
48
))
return
NULL
;
buf
=
PyString_AsString
(
s
);
sprintf
(
buf
,
"unbound C method must be called with %s 1st argument"
,
self
->
type
->
tp_name
);
PyErr_SetObject
(
PyExc_TypeError
,
s
);
Py_DECREF
(
s
);
return
NULL
;
return
PyErr_Format
(
PyExc_TypeError
,
"unbound C method must be called with %s 1st argument"
,
"s"
,
self
->
type
->
tp_name
);
}
static
PyObject
*
...
...
@@ -372,42 +408,39 @@ CMethod_getattr(CMethod *self, char *name)
Py_INCREF
(
r
);
return
r
;
}
PyErr_SetString
(
PyExc_AttributeError
,
name
);
return
NULL
;
}
static
PyTypeObject
CMethodType
=
{
PyObject_HEAD_INIT
(
&
PyType_Type
)
0
,
/*ob_size*/
"CMethod"
,
/*tp_name*/
sizeof
(
CMethod
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
CMethod_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
CMethod_getattr
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
CMethod_call
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
/* Space for future expansion */
0L
,
0L
,
0L
,
0L
,
"Storage manager for unbound C function PyObject data"
/* Documentation string */
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"CMethod"
,
/*tp_name*/
sizeof
(
CMethod
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
CMethod_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
CMethod_getattr
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
CMethod_call
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
/* Space for future expansion */
0L
,
0L
,
0L
,
0L
,
"Storage manager for unbound C function PyObject data"
/* Documentation string */
};
/* PMethod objects: */
typedef
struct
{
PyObject_HEAD
PyTypeObject
*
type
;
PyObject
*
self
;
PyObject
*
meth
;
}
PMethod
;
#define PMethod PyECMethodObject
staticforward
PyTypeObject
PMethodType
;
...
...
@@ -420,31 +453,33 @@ staticforward PyTypeObject PMethodType;
&& ! ((PMethod*)(O))->self)
static
P
Method
*
newPMethod
(
Py
TypeObject
*
type
,
PyObject
*
meth
)
static
P
yObject
*
newPMethod
(
Py
ExtensionClass
*
type
,
PyObject
*
meth
)
{
PMethod
*
self
;
UNLESS
(
self
=
PyObject_NEW
(
PMethod
,
&
PMethodType
))
return
NULL
;
Py_INCREF
(
type
);
Py_INCREF
(
meth
);
self
->
type
=
type
;
self
->
type
=
(
PyTypeObject
*
)
type
;
self
->
self
=
NULL
;
self
->
meth
=
meth
;
return
self
;
return
(
PyObject
*
)
self
;
}
static
P
Method
*
static
P
yObject
*
bindPMethod
(
PMethod
*
m
,
PyObject
*
inst
)
{
PMethod
*
self
;
UNLESS
(
PyExtensionInstance_Check
(
inst
))
if
(
NeedsToBeBound
(
m
->
meth
))
return
CallMethodO
(
m
->
meth
,
py__of__
,
Build
(
"(O)"
,
inst
),
NULL
);
if
(
m
->
ob_refcnt
==
1
)
{
Py
Err_SetString
(
PyExc_TypeError
,
"attempt to wrap extension method using an object that
\n
"
"is not an extension class instance."
);
return
NULL
;
Py
_INCREF
(
inst
);
ASSIGN
(
m
->
self
,
inst
);
Py_INCREF
(
m
);
return
(
PyObject
*
)
m
;
}
UNLESS
(
self
=
PyObject_NEW
(
PMethod
,
&
PMethodType
))
return
NULL
;
...
...
@@ -454,15 +489,36 @@ bindPMethod(PMethod *m, PyObject *inst)
self
->
type
=
m
->
type
;
self
->
self
=
inst
;
self
->
meth
=
m
->
meth
;
return
self
;
return
(
PyObject
*
)
self
;
}
static
PyObject
*
PMethod_New
(
PyObject
*
meth
,
PyObject
*
inst
)
{
if
(
PMethod_Check
(
meth
))
return
bindPMethod
((
PMethod
*
)
meth
,
inst
);
UNLESS
(
ExtensionInstance_Check
(
inst
))
return
PyErr_Format
(
PyExc_TypeError
,
"Attempt to use %s as method for %s, which is "
"not an extension class instance."
,
"OO"
,
meth
,
inst
);
if
(
meth
=
newPMethod
(
ExtensionClassOf
(
inst
),
meth
))
UNLESS_ASSIGN
(((
PMethod
*
)
meth
)
->
self
,
inst
)
return
NULL
;
Py_INCREF
(
inst
);
return
meth
;
}
static
void
PMethod_dealloc
(
PMethod
*
self
)
{
Py_DECREF
(
self
->
type
);
#ifdef TRACE_DEALLOC
fprintf
(
stderr
,
"Deallocating PM ... "
);
#endif
Py_XDECREF
(
self
->
type
);
Py_XDECREF
(
self
->
self
);
PyMem_DEL
(
self
);
#ifdef TRACE_DEALLOC
fprintf
(
stderr
,
" Done Deallocating PM
\n
"
);
#endif
}
static
PyObject
*
...
...
@@ -470,9 +526,9 @@ call_PMethod(PMethod *self, PyObject *inst, PyObject *args, PyObject *kw)
{
PyObject
*
a
;
UNLESS
(
a
=
Py_BuildValue
(
"(O)"
,
inst
))
return
NULL
;
UNLESS_ASSIGN
(
a
,
PySequence_Concat
(
a
,
args
))
return
NULL
;
UNLESS_ASSIGN
(
a
,
PyEval_CallObjectWithKeywords
(
self
->
meth
,
a
,
kw
))
return
NULL
;
a
=
Py_BuildValue
(
"(O)"
,
inst
)
;
if
(
a
)
ASSIGN
(
a
,
PySequence_Concat
(
a
,
args
))
;
if
(
a
)
ASSIGN
(
a
,
PyEval_CallObjectWithKeywords
(
self
->
meth
,
a
,
kw
))
;
return
a
;
}
...
...
@@ -480,40 +536,49 @@ static PyObject *
PMethod_call
(
PMethod
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
int
size
;
char
*
buf
;
PyObject
*
s
;
if
(
self
->
self
)
return
call_PMethod
(
self
,
self
->
self
,
args
,
kw
);
if
((
size
=
PyTuple_Size
(
args
))
>
0
)
{
PyObject
*
first
=
0
;
PyObject
*
first
=
0
,
*
ftype
=
0
;
UNLESS
(
first
=
PyTuple_GET_ITEM
(
args
,
0
))
return
NULL
;
if
(
first
->
ob_type
==
self
->
type
||
(
PyExtensionInstance_Check
(
first
)
&&
CMethod_issubclass
(
PyExtensionClassOf
(
first
),
AsPyExtensionClass
(
self
->
type
))
if
(
!
self
->
type
||
((
ftype
=
PyObject_GetAttr
(
first
,
py__class__
))
&&
(
ftype
==
(
PyObject
*
)
self
->
type
||
(
ExtensionClass_Check
(
ftype
)
&&
CMethod_issubclass
(
AsExtensionClass
(
ftype
),
AsExtensionClass
(
self
->
type
))
)
)
)
);
{
PyObject
*
rest
=
0
;
UNLESS
(
rest
=
PySequence_GetSlice
(
args
,
1
,
size
))
return
NULL
;
return
call_PMethod
(
self
,
first
,
rest
,
kw
);
}
)
{
if
(
NeedsToBeBound
(
self
->
meth
))
{
PyObject
*
r
,
*
rest
;
UNLESS
(
r
=
CallMethodO
(
self
->
meth
,
py__of__
,
Build
(
"(O)"
,
first
),
NULL
))
return
NULL
;
UNLESS
(
rest
=
PySequence_GetSlice
(
args
,
1
,
size
))
{
Py_DECREF
(
r
);
return
NULL
;
}
ASSIGN
(
r
,
PyEval_CallObjectWithKeywords
(
r
,
rest
,
kw
));
Py_DECREF
(
rest
);
return
r
;
}
Py_DECREF
(
ftype
);
return
PyEval_CallObjectWithKeywords
(
self
->
meth
,
args
,
kw
);
}
Py_XDECREF
(
ftype
);
}
/* Call of unbound method without instance argument */
size
=
strlen
(
self
->
type
->
tp_name
);
UNLESS
(
s
=
PyString_FromStringAndSize
(
NULL
,
size
+
48
))
return
NULL
;
buf
=
PyString_AsString
(
s
);
sprintf
(
buf
,
"unbound Python method must be called with %s 1st argument"
,
self
->
type
->
tp_name
);
PyErr_SetObject
(
PyExc_TypeError
,
s
);
Py_DECREF
(
s
);
return
NULL
;
return
PyErr_Format
(
PyExc_TypeError
,
"unbound Python method must be called with %s"
" 1st argument"
,
"s"
,
self
->
type
->
tp_name
);
}
static
PyObject
*
...
...
@@ -544,37 +609,39 @@ PMethod_getattr(PMethod *self, char *name)
Py_INCREF
(
r
);
return
r
;
}
PyErr_SetString
(
PyExc_AttributeError
,
name
);
return
NULL
;
}
static
PyTypeObject
PMethodType
=
{
PyObject_HEAD_INIT
(
&
PyType_Type
)
0
,
/*ob_size*/
"Python Method"
,
/*tp_name*/
sizeof
(
PMethod
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
PMethod_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
PMethod_getattr
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
PMethod_call
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
/* Space for future expansion */
0L
,
0L
,
0L
,
0L
,
"Storage manager for unbound C function PyObject data"
/* Documentation string */
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"Python Method"
,
/*tp_name*/
sizeof
(
PMethod
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
PMethod_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
PMethod_getattr
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
PMethod_call
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
/* Space for future expansion */
0L
,
0L
,
0L
,
0L
,
"Storage manager for unbound C function PyObject data"
/* Documentation string */
};
/* Special Methods */
static
PyObject
*
CCL_getattr
(
PyExtensionClass
*
,
PyObject
*
,
int
);
#define HAS(M) (M && ((void*)M != (void*)MetaTypeUndefinedMethod))
/* Special Methods */
#define UNARY_OP(OP) \
static PyObject * \
...
...
@@ -604,7 +671,7 @@ static PyObject *
compare_by_name
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
other
;
long
r
;
UNLESS
(
PyArg_Parse
(
args
,
"O"
,
&
other
))
return
NULL
;
return
PyInt_FromLong
(
self
->
ob_type
->
tp_compare
(
self
,
other
));
}
...
...
@@ -628,8 +695,6 @@ setattr_by_name(PyObject *self, PyObject *args)
return
Py_None
;
}
#if PYTHON_API_VERSION >= 1005
static
PyObject
*
getattro_by_name
(
PyObject
*
self
,
PyObject
*
args
)
{
...
...
@@ -648,8 +713,6 @@ setattro_by_name(PyObject *self, PyObject *args)
Py_INCREF
(
Py_None
);
return
Py_None
;
}
#endif
static
PyObject
*
length_by_name
(
PyObject
*
self
,
PyObject
*
args
)
...
...
@@ -688,20 +751,24 @@ getitem_by_name(PyObject *self, PyObject *args)
static
PyCFunction
item_by_name
=
(
PyCFunction
)
getitem_by_name
;
static
PyCFunction
subscript_by_name
=
(
PyCFunction
)
getitem_by_name
;
static
int
static
PyObject
*
setitem_by_name
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
key
,
*
v
;
long
r
;
UNLESS
(
PyArg_Parse
(
args
,
"OO"
,
&
key
,
&
v
))
return
NULL
;
if
(
self
->
ob_type
->
tp_as_mapping
)
r
eturn
self
->
ob_type
->
tp_as_mapping
->
mp_ass_subscript
(
self
,
key
,
v
);
r
=
self
->
ob_type
->
tp_as_mapping
->
mp_ass_subscript
(
self
,
key
,
v
);
else
{
int
index
;
UNLESS
(
-
1
!=
(
index
=
PyInt_AsLong
(
key
)))
return
-
1
;
r
eturn
self
->
ob_type
->
tp_as_sequence
->
sq_ass_item
(
self
,
index
,
v
);
UNLESS
(
-
1
!=
(
index
=
PyInt_AsLong
(
key
)))
return
NULL
;
r
=
self
->
ob_type
->
tp_as_sequence
->
sq_ass_item
(
self
,
index
,
v
);
}
if
(
r
<
0
)
return
NULL
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyCFunction
ass_item_by_name
=
(
PyCFunction
)
setitem_by_name
;
...
...
@@ -716,14 +783,18 @@ slice_by_name(PyObject *self, PyObject *args)
return
self
->
ob_type
->
tp_as_sequence
->
sq_slice
(
self
,
i1
,
i2
);
}
static
int
static
PyObject
*
ass_slice_by_name
(
PyObject
*
self
,
PyObject
*
args
)
{
int
i1
,
i2
;
PyObject
*
v
;
long
r
;
UNLESS
(
PyArg_Parse
(
args
,
"iiO"
,
&
i1
,
&
i2
,
&
v
))
return
-
1
;
return
self
->
ob_type
->
tp_as_sequence
->
sq_ass_slice
(
self
,
i1
,
i2
,
v
);
UNLESS
(
PyArg_Parse
(
args
,
"iiO"
,
&
i1
,
&
i2
,
&
v
))
return
NULL
;
r
=
self
->
ob_type
->
tp_as_sequence
->
sq_ass_slice
(
self
,
i1
,
i2
,
v
);
if
(
r
<
0
)
return
NULL
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyObject
*
...
...
@@ -817,10 +888,9 @@ UNOP(hex)
#define FILLENTRY(T,MN,N,F,D) if(T ## _ ## MN) { \
UNLESS(-1 != PyMapping_SetItemString(dict,"__" # N "__", \
(PyObject*)newCMethod((PyTypeObject *)type,"__" # N "__", \
(PyCFunction)MN ## _by_name, F, # D))) \
goto err; \
}
newCMethod(type, NULL, "__" # N "__", \
(PyCFunction)MN ## _by_name, F, # D))) \
goto err; }
static
PyObject
*
getBaseDictionary
(
PyExtensionClass
*
type
)
...
...
@@ -830,7 +900,8 @@ getBaseDictionary(PyExtensionClass *type)
PyMappingMethods
*
mm
;
PyObject
*
dict
;
UNLESS
(
dict
=
PyDict_New
())
return
NULL
;
UNLESS
(
dict
=
type
->
class_dictionary
)
UNLESS
(
dict
=
PyDict_New
())
return
NULL
;
FILLENTRY
(
type
->
tp
,
repr
,
repr
,
0
,
"convert to an expression string"
);
FILLENTRY
(
type
->
tp
,
hash
,
hash
,
0
,
"compute a hash value"
);
...
...
@@ -838,11 +909,8 @@ getBaseDictionary(PyExtensionClass *type)
FILLENTRY
(
type
->
tp
,
compare
,
comp
,
0
,
"compare with another object"
);
FILLENTRY
(
type
->
tp
,
getattr
,
getattr
,
0
,
"Get an attribute"
);
FILLENTRY
(
type
->
tp
,
setattr
,
setattr
,
0
,
"Set an attribute"
);
#if PYTHON_API_VERSION >= 1005
FILLENTRY
(
type
->
tp
,
getattro
,
getattr
,
0
,
"Get an attribute"
);
FILLENTRY
(
type
->
tp
,
setattro
,
setattr
,
0
,
"Set an attribute"
);
#endif
if
(
sm
=
type
->
tp_as_sequence
)
{
...
...
@@ -900,24 +968,109 @@ err:
return
NULL
;
}
#undef HAS
#undef UNARY_OP
#undef BINOP
#undef UNOP
#undef FILLENTRY
PyObject
*
EC_reduce
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
state
=
0
;
if
(
args
=
PyObject_GetAttr
(
self
,
py__getinitargs__
))
{
UNLESS_ASSIGN
(
args
,
PyEval_CallObject
(
args
,
NULL
))
return
NULL
;
UNLESS_ASSIGN
(
args
,
PySequence_Tuple
(
args
))
return
NULL
;
}
else
{
PyErr_Clear
();
args
=
PyTuple_New
(
0
);
}
if
(
state
=
PyObject_GetAttr
(
self
,
py__getstate__
))
{
UNLESS_ASSIGN
(
state
,
PyEval_CallObject
(
state
,
NULL
))
goto
err
;
ASSIGN
(
args
,
Py_BuildValue
(
"OOO"
,
self
->
ob_type
,
args
,
state
));
Py_DECREF
(
state
);
}
else
{
PyErr_Clear
();
if
(
state
=
PyObject_GetAttr
(
self
,
py__dict__
))
{
ASSIGN
(
args
,
Py_BuildValue
(
"OOO"
,
self
->
ob_type
,
args
,
state
));
Py_DECREF
(
state
);
}
else
{
PyErr_Clear
();
ASSIGN
(
args
,
Py_BuildValue
(
"OO"
,
self
->
ob_type
,
args
));
}
}
return
args
;
err:
Py_DECREF
(
args
);
return
NULL
;
}
static
PyObject
*
inheritedAttribute
(
PyExtensionClass
*
self
,
PyObject
*
name
)
{
UNLESS
(
name
)
return
PyErr_Format
(
PyExc_TypeError
,
"expected one argument, and none given"
,
NULL
);
return
CCL_getattr
(
self
,
name
,
1
);
}
static
PyObject
*
inheritedClassAttribute
(
PyExtensionClass
*
self
,
PyObject
*
name
)
{
UNLESS
(
name
)
return
PyErr_Format
(
PyExc_TypeError
,
"expected one argument, and none given"
,
NULL
);
UNLESS
(
name
=
PySequence_Concat
(
pyclass_
,
name
))
return
NULL
;
UNLESS_ASSIGN
(
name
,
CCL_getattr
(
self
,
name
,
1
))
return
NULL
;
if
(
UnboundPMethod_Check
(
name
))
ASSIGN
(
name
,
bindPMethod
((
PMethod
*
)
name
,(
PyObject
*
)
self
));
return
name
;
}
struct
PyMethodDef
ECI_methods
[]
=
{
{
"__reduce__"
,(
PyCFunction
)
EC_reduce
,
0
,
"__reduce__() -- Reduce an instance into it's class and creation data"
},
{
NULL
,
NULL
}
/* sentinel */
};
static
PyObject
*
initializeBaseExtensionClass
(
PyExtensionClass
*
self
)
{
PyMethodChain
*
chain
;
PyMethodChain
*
chain
,
top
=
{
ECI_methods
,
NULL
}
;
PyObject
*
dict
;
self
->
ob_type
=
(
PyTypeObject
*
)
&
CCLt
ype
;
self
->
ob_type
=
(
PyTypeObject
*
)
&
ECT
ype
;
Py_INCREF
(
self
->
ob_type
);
UNLESS
(
dict
=
self
->
class_dictionary
=
getBaseDictionary
(
self
))
return
NULL
;
if
(
self
->
tp_name
)
{
PyObject
*
name
;
UNLESS
(
name
=
PyString_FromString
(
self
->
tp_name
))
goto
err
;
if
(
0
>
PyMapping_SetItemString
(
dict
,
"__doc__"
,
name
))
goto
err
;
Py_DECREF
(
name
);
}
else
if
(
0
>
PyMapping_SetItemString
(
dict
,
"__doc__"
,
Py_None
))
goto
err
;
top
.
link
=&
(
self
->
methods
);
chain
=&
(
self
->
methods
)
;
chain
=&
top
;
while
(
chain
!=
NULL
)
{
PyMethodDef
*
ml
=
chain
->
methods
;
...
...
@@ -927,8 +1080,7 @@ initializeBaseExtensionClass(PyExtensionClass *self)
{
UNLESS
(
-
1
!=
PyMapping_SetItemString
(
dict
,
ml
->
ml_name
,
(
PyObject
*
)
newCMethod
((
PyTypeObject
*
)
self
,
newCMethod
(
self
,
NULL
,
ml
->
ml_name
,
ml
->
ml_meth
,
ml
->
ml_flags
,
...
...
@@ -953,18 +1105,34 @@ initializeBaseExtensionClass(PyExtensionClass *self)
chain
=
chain
->
link
;
}
return
(
PyObject
*
)
self
;
err:
Py_DECREF
(
dict
);
return
NULL
;
}
static
void
CCL_dealloc
(
PyExtensionClass
*
self
)
{
#ifdef TRACE_DEALLOC
fprintf
(
stderr
,
"Deallocating %s
\n
"
,
self
->
tp_name
);
#endif
Py_XDECREF
(
self
->
class_dictionary
);
Py_XDECREF
(
self
->
bases
);
if
(
self
->
bases
)
{
/* If we are a subclass, then we strduped our name */
free
(
self
->
tp_name
);
/* And we allocated our own protocol structures */
if
(
self
->
tp_as_number
)
free
(
self
->
tp_as_number
);
if
(
self
->
tp_as_sequence
)
free
(
self
->
tp_as_sequence
);
if
(
self
->
tp_as_mapping
)
free
(
self
->
tp_as_mapping
);
Py_DECREF
(
self
->
bases
);
}
Py_XDECREF
(
self
->
ob_type
);
PyMem_DEL
(
self
);
}
static
PyObject
*
CCL_getattr
();
static
PyObject
*
ExtensionClass_FindInstanceAttribute
(
PyObject
*
inst
,
PyObject
*
oname
,
...
...
@@ -985,12 +1153,13 @@ ExtensionClass_FindInstanceAttribute(PyObject *inst, PyObject *oname,
if
(
*
name
==
'_'
&&
name
[
1
]
==
'_'
)
{
if
(
strcmp
(
name
+
2
,
"class__"
)
==
0
)
char
*
n
=
name
+
2
;
if
(
*
n
==
'c'
&&
strcmp
(
n
,
"class__"
)
==
0
)
{
Py_INCREF
(
self
);
return
(
PyObject
*
)
self
;
}
if
(
self
->
bases
&&
strcmp
(
name
+
2
,
"dict__"
)
==
0
)
if
(
self
->
bases
&&
*
n
==
'd'
&&
strcmp
(
n
,
"dict__"
)
==
0
)
{
r
=
INSTANCE_DICT
(
inst
);
Py_INCREF
(
r
);
...
...
@@ -1001,39 +1170,22 @@ ExtensionClass_FindInstanceAttribute(PyObject *inst, PyObject *oname,
if
(
self
->
bases
)
{
r
=
INSTANCE_DICT
(
inst
);
r
=
PyObject_GetItem
(
r
,
oname
);
if
((
r
=
PyObject_GetItem
(
r
,
oname
))
&&
NeedsToBeBound
(
r
))
{
ASSIGN
(
r
,
CallMethodO
(
r
,
py__of__
,
Build
(
"(O)"
,
inst
),
NULL
));
UNLESS
(
r
)
return
NULL
;
}
}
UNLESS
(
r
)
{
PyErr_Clear
();
UNLESS
(
r
=
CCL_getattr
(
self
,
oname
,
name
))
return
NULL
;
UNLESS
(
r
=
CCL_getattr
(
self
,
oname
,
0
))
return
NULL
;
/* We got something from our class, maybe its an unbound method. */
if
(
UnboundCMethod_Check
(
r
))
{
UNLESS_ASSIGN
(
r
,(
PyObject
*
)
bindCMethod
((
CMethod
*
)
r
,
inst
))
return
NULL
;
}
ASSIGN
(
r
,(
PyObject
*
)
bindCMethod
((
CMethod
*
)
r
,
inst
));
else
if
(
UnboundPMethod_Check
(
r
))
{
PyObject
*
m
;
m
=
((
PMethod
*
)
r
)
->
meth
;
if
(
PyExtensionInstance_Check
(
m
)
&&
(
PyExtensionClassOf
(
m
)
->
class_flags
&
EXTENSIONCLASS_BINDABLE_FLAG
)
)
{
UNLESS_ASSIGN
(
r
,
PyObject_CallMethod
(
m
,
"__bind_to_object__"
,
"O"
,
inst
))
return
NULL
;
}
else
{
UNLESS_ASSIGN
(
r
,(
PyObject
*
)
bindPMethod
((
PMethod
*
)
r
,
inst
))
return
NULL
;
}
}
ASSIGN
(
r
,
bindPMethod
((
PMethod
*
)
r
,
inst
));
}
return
r
;
...
...
@@ -1061,69 +1213,33 @@ static int
subclass_simple_setattr
(
PyObject
*
self
,
char
*
name
,
PyObject
*
v
);
static
PyObject
*
CCL_getattr
(
PyExtensionClass
*
self
,
PyObject
*
oname
,
char
*
name
)
CCL_getattr
(
PyExtensionClass
*
self
,
PyObject
*
oname
,
int
look_super
)
{
PyObject
*
r
;
int
local
=
1
;
char
*
n
;
if
(
!
name
)
return
NULL
;
PyObject
*
r
=
0
;
if
(
*
name
==
'.'
)
{
n
=
name
+
1
;
if
(
*
n
==
0
)
return
(
PyObject
*
)
EC_findiattrs
;
if
(
*
n
==
'o'
&&
n
[
1
]
==
0
)
return
(
PyObject
*
)
EC_findiattro
;
if
(
*
n
==
's'
&&
n
[
1
]
==
0
)
return
(
PyObject
*
)
subclass_simple_setattr
;
}
if
(
*
name
==
'_'
&&
name
[
1
]
==
'_'
)
{
n
=
name
+
2
;
if
(
strcmp
(
n
,
"doc__"
)
==
0
&&
self
->
tp_doc
)
return
PyString_FromString
(
self
->
tp_doc
);
if
(
strcmp
(
n
,
"name__"
)
==
0
)
return
PyString_FromString
(
self
->
tp_name
);
if
(
strcmp
(
n
,
"dict__"
)
==
0
)
{
Py_INCREF
(
self
->
class_dictionary
);
return
self
->
class_dictionary
;
}
if
(
strcmp
(
n
,
"bases__"
)
==
0
)
{
if
(
self
->
bases
)
{
Py_INCREF
(
self
->
bases
);
return
self
->
bases
;
}
else
return
PyTuple_New
(
0
);
}
}
r
=
PyObject_GetItem
(
self
->
class_dictionary
,
oname
);
if
(
!
look_super
)
r
=
PyObject_GetItem
(
self
->
class_dictionary
,
oname
);
UNLESS
(
r
)
{
local
=
0
;
if
(
self
->
bases
)
{
int
n
,
i
;
PyObject
*
c
;
n
=
PyTuple_Size
(
self
->
bases
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
PyErr_Clear
();
c
=
PyTuple_GET_ITEM
(
self
->
bases
,
i
);
if
(
r
=
PyObject_GetAttr
(
c
,
oname
))
break
;
if
(
ExtensionClass_Check
(
c
))
r
=
CCL_getattr
(
AsExtensionClass
(
c
),
oname
,
0
);
else
r
=
PyObject_GetAttr
(
c
,
oname
);
if
(
r
)
break
;
}
}
UNLESS
(
r
)
{
PyObject
*
t
,
*
v
,
*
tb
;
char
*
s
;
PyErr_Fetch
(
&
t
,
&
v
,
&
tb
);
if
(
t
==
PyExc_KeyError
&&
PyObject_Compare
(
v
,
oname
)
==
0
)
...
...
@@ -1137,64 +1253,99 @@ CCL_getattr(PyExtensionClass *self, PyObject *oname, char *name)
}
}
if
(
PyFunction_Check
(
r
)
||
(
PyExtensionInstance_Check
(
r
)
&&
(
PyExtensionClassOf
(
r
)
->
class_flags
&
EXTENSIONCLASS_BINDABLE_FLAG
)
)
)
if
(
PyFunction_Check
(
r
)
||
NeedsToBeBound
(
r
))
{
UNLESS_ASSIGN
(
r
,(
PyObject
*
)
newPMethod
((
PyTypeObject
*
)
self
,
r
))
return
NULL
;
UNLESS_ASSIGN
(
r
,
newPMethod
(
self
,
r
))
return
NULL
;
}
else
if
(
PyMethod_Check
(
r
)
&&
!
PyMethod_Self
(
r
))
{
UNLESS_ASSIGN
(
r
,(
PyObject
*
)
newPMethod
((
PyTypeObject
*
)
self
,
PyMethod_Function
(
r
)))
UNLESS_ASSIGN
(
r
,
newPMethod
(
self
,
PyMethod_Function
(
r
)))
return
NULL
;
}
else
local
=
0
;
if
(
local
)
/* We have a PMethod that we built from our dict, cache it */
{
UNLESS
(
-
1
!=
PyObject_SetItem
(
self
->
class_dictionary
,
oname
,
r
))
PyErr_Clear
();
/* Oh well */
}
return
r
;
}
PyObject
*
CCL_getattrs
(
PyExtensionClass
*
self
,
char
*
name
)
{
PyObject
*
s
,
*
r
;
UNLESS
(
s
=
PyString_FromString
(
name
))
return
NULL
;
r
=
CCL_getattr
(
self
,
s
,
name
);
Py_DECREF
(
s
);
return
r
;
}
static
int
CCL_setattrs
(
self
,
name
,
v
)
PyExtensionClass
*
self
;
char
*
name
;
PyObject
*
v
;
static
PyObject
*
CCL_reduce
(
PyExtensionClass
*
self
,
PyObject
*
args
)
{
return
Py
Mapping_SetItemString
(
self
->
class_dictionary
,
name
,
v
);
return
Py
String_FromString
(
self
->
tp_name
);
}
PyObject
*
CCL_getattro
(
PyExtensionClass
*
self
,
PyObject
*
name
)
{
return
CCL_getattr
(
self
,
name
,
PyString_AsString
(
name
));
char
*
n
,
*
nm
=
0
;
PyObject
*
r
;
if
(
PyString_Check
(
name
)
&&
(
n
=
nm
=
PyString_AS_STRING
((
PyStringObject
*
)
name
)))
{
if
(
*
n
==
'_'
&&
*++
n
==
'_'
)
{
switch
(
*++
n
)
{
case
's'
:
if
(
strcmp
(
n
,
"safe_for_unpickling__"
)
==
0
)
return
PyInt_FromLong
(
1
);
break
;
case
'n'
:
if
(
strcmp
(
n
,
"name__"
)
==
0
)
return
PyString_FromString
(
self
->
tp_name
);
break
;
case
'r'
:
if
(
strcmp
(
n
,
"reduce__"
)
==
0
)
return
newCMethod
(
self
,(
PyObject
*
)
self
,
"__reduce__"
,(
PyCFunction
)
CCL_reduce
,
0
,
"__reduce__() -- Reduce the class to a class name"
);
break
;
case
'd'
:
if
(
strcmp
(
n
,
"dict__"
)
==
0
)
{
Py_INCREF
(
self
->
class_dictionary
);
return
self
->
class_dictionary
;
}
break
;
case
'b'
:
if
(
strcmp
(
n
,
"bases__"
)
==
0
)
{
if
(
self
->
bases
)
{
Py_INCREF
(
self
->
bases
);
return
self
->
bases
;
}
else
return
PyTuple_New
(
0
);
}
break
;
}
}
}
if
(
strcmp
(
nm
,
"inheritedAttribute"
)
==
0
)
{
return
newCMethod
(
self
,(
PyObject
*
)
self
,
"inheritedAttribute"
,(
PyCFunction
)
inheritedAttribute
,
0
,
"look up an attribute in a class's super classes"
);
}
if
(
nm
&&
*
nm
++==
'c'
&&
*
nm
++==
'l'
&&
*
nm
++==
'a'
&&
*
nm
++==
's'
&&
*
nm
++==
's'
&&
*
nm
==
'_'
)
{
UNLESS
(
r
=
CCL_getattr
(
self
,
name
,
0
))
return
NULL
;
if
(
UnboundPMethod_Check
(
r
))
ASSIGN
(
r
,
bindPMethod
((
PMethod
*
)
r
,(
PyObject
*
)
self
));
return
r
;
}
if
(
r
=
CCL_getattr
(
self
,
name
,
0
))
return
r
;
return
NULL
;
}
static
int
CCL_setattro
(
PyExtensionClass
*
self
,
PyObject
*
name
,
PyObject
*
v
)
{
if
(
UnboundCMethod_Check
(
v
))
if
(
v
&&
UnboundCMethod_Check
(
v
))
{
char
*
n
;
PyNumberMethods
*
nm
;
...
...
@@ -1319,19 +1470,14 @@ static PyObject *
CCL_call
(
PyExtensionClass
*
self
,
PyObject
*
arg
,
PyObject
*
kw
)
{
PyObject
*
inst
=
0
,
*
init
=
0
,
*
args
=
0
;
int
check
;
struct
Dataless
{
PyObject_HEAD
};
typedef
struct
{
PyObject_VAR_HEAD
}
PyVarObject__
;
if
(
PyArg_ParseTuple
(
arg
,
"Oi"
,
&
inst
,
&
check
)
)
if
(
!
self
->
tp_dealloc
)
{
if
(
check
==
42
&&
inst
->
ob_type
==&
PyType_Type
)
{
initializeBaseExtensionClass
((
PyExtensionClass
*
)
inst
);
return
(
PyObject
*
)
inst
;
}
PyErr_SetString
(
PyExc_TypeError
,
"Attempt to create instance of an abstract type"
);
return
NULL
;
}
else
PyErr_Clear
();
if
(
self
->
tp_itemsize
)
{
...
...
@@ -1339,17 +1485,17 @@ CCL_call(PyExtensionClass *self, PyObject *arg, PyObject *kw)
PyObject
*
var_size
;
int
size
;
if
(
var_size
=
CCL_getattr
o
(
self
,
py__var_size__
))
if
(
var_size
=
CCL_getattr
(
self
,
py__var_size__
,
0
))
{
UNLESS_ASSIGN
(
var_size
,
PyObject_CallObject
(
var_size
,
arg
s
))
UNLESS_ASSIGN
(
var_size
,
PyObject_CallObject
(
var_size
,
arg
))
return
NULL
;
}
else
{
UNLESS
(
-
1
!=
(
size
=
PyTuple_Size
(
arg
s
)))
return
NULL
;
UNLESS
(
-
1
!=
(
size
=
PyTuple_Size
(
arg
)))
return
NULL
;
if
(
size
>
0
)
{
var_size
=
PyTuple_GET_ITEM
(
arg
s
,
0
);
var_size
=
PyTuple_GET_ITEM
(
arg
,
0
);
if
(
PyInt_Check
(
var_size
))
size
=
PyInt_AsLong
(
var_size
);
else
...
...
@@ -1385,9 +1531,7 @@ CCL_call(PyExtensionClass *self, PyObject *arg, PyObject *kw)
UNLESS
(
INSTANCE_DICT
(
inst
)
=
PyDict_New
())
goto
err
;
}
if
(
init
=
CCL_getattro
(
self
,
py__init__
))
if
(
init
=
CCL_getattr
(
self
,
py__init__
,
0
))
{
UNLESS
(
args
=
Py_BuildValue
(
"(O)"
,
inst
))
goto
err
;
if
(
arg
)
UNLESS_ASSIGN
(
args
,
PySequence_Concat
(
args
,
arg
))
goto
err
;
...
...
@@ -1397,7 +1541,6 @@ CCL_call(PyExtensionClass *self, PyObject *arg, PyObject *kw)
}
else
PyErr_Clear
();
return
inst
;
err:
Py_DECREF
(
inst
);
...
...
@@ -1409,29 +1552,24 @@ err:
static
PyObject
*
CCL_repr
(
PyExtensionClass
*
self
)
{
PyObject
*
s
;
int
l
;
char
*
buf
,
p
[
64
];
char
p
[
128
];
sprintf
(
p
,
"%p"
,
self
);
l
=
strlen
(
self
->
ob_type
->
tp_name
)
+
strlen
(
p
);
UNLESS
(
s
=
PyString_FromStringAndSize
(
NULL
,
l
+
22
))
return
NULL
;
buf
=
PyString_AsString
(
s
);
sprintf
(
buf
,
"<extension class %s at %p>"
,
self
->
tp_name
,
self
);
return
s
;
return
PyString_Build
(
"<extension class %s at %s>"
,
"ss"
,
self
->
tp_name
,
p
);
}
static
PyTypeObject
CCLtype_class
=
{
PyObject_HEAD_INIT
(
&
PyType_Type
)
static
PyTypeObject
ECTypeType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"
C Class Class"
,
/*tp_name*/
"
ExtensionClass Class"
,
/*tp_name*/
sizeof
(
PyExtensionClass
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
CCL_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
CCL_getattrs
,
/*tp_getattr*/
(
setattrfunc
)
CCL_setattrs
,
/*tp_setattr*/
(
getattrfunc
)
0
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
CCL_repr
,
/*tp_repr*/
0
,
/*tp_as_number*/
...
...
@@ -1440,14 +1578,10 @@ static PyTypeObject CCLtype_class = {
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
CCL_call
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
#if PYTHON_API_VERSION >= 1005
(
getattrofunc
)
CCL_getattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
CCL_setattro
,
/*tp_setattr with object key*/
#else
/* Space for future expansion */
0L
,
0L
,
#endif
0L
,
0L
,
"Class of C classes"
/* Documentation string */
};
...
...
@@ -1468,7 +1602,7 @@ subclass_getspecial(PyObject *inst, PyObject *oname)
UNLESS
(
r
)
{
PyErr_Clear
();
r
=
CCL_getattr
(
self
,
oname
,
""
);
r
=
CCL_getattr
(
self
,
oname
,
0
);
}
return
r
;
...
...
@@ -1477,36 +1611,34 @@ subclass_getspecial(PyObject *inst, PyObject *oname)
static
PyObject
*
subclass_getattro
(
PyObject
*
self
,
PyObject
*
name
)
{
PyObject
*
r
=
0
;
PyObject
*
r
;
if
(
!
name
)
return
NULL
;
UNLESS
(
r
=
EC_findiattro
(
self
,
name
))
{
PyErr_Clear
();
UNLESS
(
r
=
EC_findiattro
(
self
,
py__getattr__
))
return
NULL
;
UNLESS_ASSIGN
(
r
,
PyObject_CallFunction
(
r
,
"O"
,
name
))
return
NULL
;
r
=
EC_findiattro
(
self
,
py__getattr__
)
;
if
(
r
)
ASSIGN
(
r
,
PyObject_CallFunction
(
r
,
"O"
,
name
))
;
}
return
r
;
}
static
PyObject
*
subclass_getattrs
(
PyObject
*
self
,
char
*
name
)
{
return
subclass_getattro
(
self
,
PyString_FromString
(
name
));
}
static
int
subclass_simple_setattro
(
PyObject
*
self
,
PyObject
*
name
,
PyObject
*
v
)
{
Py_INCREF
(
v
);
return
PyDict_SetItem
(
INSTANCE_DICT
(
self
),
name
,
v
);
if
(
v
)
return
PyDict_SetItem
(
INSTANCE_DICT
(
self
),
name
,
v
);
else
return
PyDict_DelItem
(
INSTANCE_DICT
(
self
),
name
);
}
static
int
subclass_simple_setattr
(
PyObject
*
self
,
char
*
name
,
PyObject
*
v
)
{
Py_INCREF
(
v
);
return
PyDict_SetItemString
(
INSTANCE_DICT
(
self
),
name
,
v
);
if
(
v
)
return
PyDict_SetItemString
(
INSTANCE_DICT
(
self
),
name
,
v
);
else
return
PyDict_DelItemString
(
INSTANCE_DICT
(
self
),
name
);
}
static
int
...
...
@@ -1516,16 +1648,26 @@ subclass_setattr(PyObject *self, PyObject *oname, char *name, PyObject *v)
if
(
!
name
)
return
-
1
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__setattr__
))
goto
default_setattr
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
setattr_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
if
(
!
v
&&
(
m
=
subclass_getspecial
(
self
,
py__delattr__
)))
{
UNLESS
(
-
1
!=
AsCMethod
(
m
)
->
type
->
tp_setattr
(
self
,
name
,
v
))
goto
dictionary_setattr
;
return
0
;
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
self
,
oname
))
return
-
1
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
oname
))
return
-
1
;
Py_DECREF
(
m
);
return
0
;
}
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__setattr__
))
goto
default_setattr
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
setattr_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
UNLESS
(
-
1
!=
AsCMethod
(
m
)
->
type
->
tp_setattr
(
self
,
name
,
v
))
goto
dictionary_setattr
;
return
0
;
}
#if PYTHON_API_VERSION >= 1005
else
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
setattro_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
...
...
@@ -1534,7 +1676,7 @@ subclass_setattr(PyObject *self, PyObject *oname, char *name, PyObject *v)
goto
dictionary_setattr
;
return
0
;
}
#endif
if
(
!
v
)
goto
default_setattr
;
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OOO"
,
self
,
oname
,
v
))
return
-
1
;
...
...
@@ -1574,18 +1716,6 @@ default_setattr:
return
subclass_simple_setattro
(
self
,
oname
,
v
);
}
static
int
subclass_setattrs
(
PyObject
*
self
,
char
*
name
,
PyObject
*
v
)
{
PyObject
*
s
;
int
r
;
UNLESS
(
s
=
PyString_FromString
(
name
))
return
-
1
;
r
=
subclass_setattr
(
self
,
s
,
name
,
v
);
Py_DECREF
(
s
);
return
r
;
}
static
int
subclass_setattro
(
PyObject
*
self
,
PyObject
*
name
,
PyObject
*
v
)
{
...
...
@@ -1641,67 +1771,59 @@ subclass_hash(PyObject *self)
return
r
;
}
static
PyObject
*
default_subclass_repr
(
PyObject
*
self
)
{
char
p
[
64
];
PyErr_Clear
();
sprintf
(
p
,
"%p"
,
self
);
return
PyString_Build
(
"<%s instance at %s>"
,
"ss"
,
self
->
ob_type
->
tp_name
,
p
);
}
static
PyObject
*
subclass_repr
(
PyObject
*
self
)
{
PyObject
*
m
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__repr__
))
{
int
l
;
char
*
buf
,
p
[
64
];
return
default_subclass_repr
(
self
);
PyErr_Clear
();
sprintf
(
p
,
"%p"
,
self
);
l
=
strlen
(
self
->
ob_type
->
tp_name
)
+
strlen
(
p
);
UNLESS
(
m
=
PyString_FromStringAndSize
(
NULL
,
l
+
15
))
return
NULL
;
buf
=
PyString_AsString
(
m
);
sprintf
(
buf
,
"<%s instance at %s>"
,
self
->
ob_type
->
tp_name
,
p
);
return
m
;
}
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
repr_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
UNLESS_ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_repr
(
self
))
return
NULL
;
}
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_repr
(
self
));
else
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
self
));
else
{
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
self
))
return
NULL
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
""
))
return
NULL
;
}
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
""
));
return
m
;
}
static
PyObject
*
subclass_call
(
PyObject
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
PyObject
*
m
,
*
a
=
0
;
PyObject
*
m
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__call__
))
return
NULL
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
call_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
UNLESS_ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_call
(
self
,
args
,
kw
))
return
NULL
;
}
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_call
(
self
,
args
,
kw
));
else
{
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS
(
a
=
Py_BuildValue
(
"(O)"
,
self
))
goto
err
;
UNLESS_ASSIGN
(
a
,
PySequence_Concat
(
a
,
args
))
goto
err
;
args
=
a
;
PyObject
*
a
;
a
=
Py_BuildValue
(
"(O)"
,
self
);
if
(
a
)
ASSIGN
(
a
,
PySequence_Concat
(
a
,
args
));
if
(
a
)
ASSIGN
(
m
,
PyEval_CallObjectWithKeywords
(
m
,
a
,
kw
));
else
ASSIGN
(
m
,
NULL
);
Py_XDECREF
(
a
);
}
UNLESS_ASSIGN
(
m
,
PyEval_CallObjectWithKeywords
(
m
,
args
,
kw
))
goto
err
;
else
ASSIGN
(
m
,
PyEval_CallObjectWithKeywords
(
m
,
args
,
kw
));
}
Py_XDECREF
(
a
);
return
m
;
err:
Py_XDECREF
(
m
);
Py_XDECREF
(
a
);
}
static
PyObject
*
...
...
@@ -1716,18 +1838,11 @@ subclass_str(PyObject *self)
}
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
str_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
UNLESS_ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_str
(
self
))
return
NULL
;
}
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_str
(
self
));
else
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
self
));
else
{
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
self
))
return
NULL
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
""
))
return
NULL
;
}
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
""
));
return
m
;
}
...
...
@@ -1739,19 +1854,11 @@ subclass_ ## M(PyObject *self, PyObject *v) \
UNLESS(m=subclass_getspecial(self,py__ ## N ## __)) return NULL; \
if(UnboundCMethod_Check(m) && AsCMethod(m)->meth==M ## _by_name \
&& SubclassInstance_Check(self,AsCMethod(m)->type)) \
{ \
UNLESS_ASSIGN(m,PyNumber_ ## A(self,v)) \
return NULL; \
} \
ASSIGN(m,PyNumber_ ## A(self,v)); \
else if(UnboundEMethod_Check(m)) \
ASSIGN(m,PyObject_CallFunction(m,"OO",self,v)); \
else \
{ \
if(UnboundEMethod_Check(m)) \
{ \
UNLESS_ASSIGN(m,PyObject_CallFunction(m,"OO",self,v)) \
return NULL; \
} \
else UNLESS_ASSIGN(m,PyObject_CallFunction(m,"O",v)) return NULL; \
} \
ASSIGN(m,PyObject_CallFunction(m,"O",v)); \
return m; \
}
...
...
@@ -1768,23 +1875,14 @@ subclass_power(PyObject *self, PyObject *v, PyObject *w)
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__pow__
))
return
NULL
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
power_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
UNLESS_ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_number
->
nb_power
(
self
,
v
,
w
))
return
NULL
;
}
else
{
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OOO"
,
self
,
v
,
w
))
return
NULL
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
v
,
w
))
return
NULL
;
}
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_number
->
nb_power
(
self
,
v
,
w
));
else
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OOO"
,
self
,
v
,
w
));
else
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
v
,
w
));
return
m
;
}
BINSUB
(
divmod
,
divmod
,
Divmod
)
BINSUB
(
lshift
,
lshift
,
Lshift
)
BINSUB
(
rshift
,
rshift
,
Rshift
)
...
...
@@ -1807,8 +1905,7 @@ subclass_coerce(PyObject **self, PyObject **v)
{
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
*
self
,
v
))
return
NULL
;
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
*
self
,
v
))
return
-
1
;
}
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
*
v
))
return
-
1
;
if
(
m
==
Py_None
)
r
=-
1
;
...
...
@@ -1832,19 +1929,11 @@ subclass_ ## M(PyObject *self) \
UNLESS(m=subclass_getspecial(self,py__ ## N ## __)) return NULL; \
if(UnboundCMethod_Check(m) && AsCMethod(m)->meth==M ## _by_name \
&& SubclassInstance_Check(self,AsCMethod(m)->type)) \
{ \
UNLESS_ASSIGN(m,AsCMethod(m)->type->tp_as_number->nb_ ## M(self)) \
return NULL; \
} \
ASSIGN(m,AsCMethod(m)->type->tp_as_number->nb_ ## M(self)); \
else if(UnboundEMethod_Check(m)) \
ASSIGN(m,PyObject_CallFunction(m,"O",self)); \
else \
{ \
if(UnboundEMethod_Check(m)) \
{ \
UNLESS_ASSIGN(m,PyObject_CallFunction(m,"O",self)) \
return NULL; \
} \
else UNLESS_ASSIGN(m,PyObject_CallFunction(m,"")) return NULL; \
} \
ASSIGN(m,PyObject_CallFunction(m,"")); \
return m; \
}
...
...
@@ -1931,11 +2020,12 @@ subclass_length(PyObject *self)
else
return
t
->
tp_as_mapping
->
mp_length
(
self
);
}
else
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
""
))
return
-
1
;
r
=
PyInt_AsLong
(
m
);
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
self
))
return
-
1
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
""
))
return
-
1
;
r
=
PyInt_AsLong
(
m
);
Py_DECREF
(
m
);
return
r
;
}
...
...
@@ -1957,20 +2047,46 @@ subclass_item(PyObject *self, int index)
return
t
->
tp_as_sequence
->
sq_item
(
self
,
index
);
}
}
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"i"
,
index
))
goto
err
;
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"Oi"
,
self
,
index
));
else
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"i"
,
index
));
return
m
;
}
static
PyObject
*
subclass_slice
(
PyObject
*
self
,
int
i1
,
int
i2
)
{
PyObject
*
m
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__getslice__
))
return
NULL
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
slice_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_slice
(
self
,
i1
,
i2
));
else
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"Oii"
,
self
,
i1
,
i2
));
else
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"ii"
,
i1
,
i2
));
return
m
;
err:
Py_DECREF
(
m
);
return
NULL
;
}
static
long
subclass_ass_item
(
PyObject
*
self
,
int
index
,
PyObject
*
v
)
{
long
r
;
PyObject
*
m
;
PyExtensionClass
*
t
;
if
(
!
v
&&
(
m
=
subclass_getspecial
(
self
,
py__delitem__
)))
{
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"Oi"
,
self
,
index
))
return
-
1
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"i"
,
index
))
return
-
1
;
Py_DECREF
(
m
);
return
0
;
}
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__setitem__
))
return
-
1
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
setitem_by_name
...
...
@@ -1983,32 +2099,18 @@ subclass_ass_item(PyObject *self, int index, PyObject *v)
return
t
->
tp_as_sequence
->
sq_ass_item
(
self
,
index
,
v
);
}
}
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"iO"
,
index
,
v
))
return
-
1
;
r
=
PyInt_AsLong
(
m
);
Py_DECREF
(
m
);
return
r
;
err:
Py_DECREF
(
m
);
return
NULL
;
}
static
PyObject
*
subclass_slice
(
PyObject
*
self
,
int
i1
,
int
i2
)
{
PyObject
*
m
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__getslice__
))
return
NULL
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
slice_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
if
(
!
v
)
{
UNLESS_ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_slice
(
self
,
i1
,
i2
))
return
NULL
;
PyErr_SetObject
(
PyExc_AttributeError
,
py__delitem__
);
return
-
1
;
}
else
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"
ii"
,
i1
,
i2
))
return
NULL
;
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"
OiO"
,
self
,
index
,
v
))
return
-
1
;
}
return
m
;
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"iO"
,
index
,
v
))
return
-
1
;
Py_DECREF
(
m
);
return
0
;
}
static
int
...
...
@@ -2017,18 +2119,41 @@ subclass_ass_slice(PyObject *self, int i1, int i2, PyObject *v)
PyObject
*
m
;
long
r
;
if
(
!
v
&&
(
m
=
subclass_getspecial
(
self
,
py__delslice__
)))
{
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"Oii"
,
self
,
i1
,
i2
))
return
-
1
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"ii"
,
i1
,
i2
))
return
-
1
;
Py_DECREF
(
m
);
return
0
;
}
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__setslice__
))
return
-
1
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
ass_slice_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
r
=
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_ass_slice
(
self
,
i1
,
i2
,
v
);
else
{
r
=
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_ass_slice
(
self
,
i1
,
i2
,
v
);
Py_DECREF
(
m
);
return
r
;
}
if
(
!
v
)
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"iiO"
,
i1
,
i2
,
v
))
return
-
1
;
r
=
PyInt_AsLong
(
m
);
PyErr_SetObject
(
PyExc_AttributeError
,
py__delslice__
);
return
-
1
;
}
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OiiO"
,
self
,
i1
,
i2
,
v
))
return
-
1
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"iiO"
,
i1
,
i2
,
v
))
return
-
1
;
Py_DECREF
(
m
);
return
r
;
return
0
;
}
static
PyObject
*
...
...
@@ -2071,16 +2196,14 @@ subclass_concat(PyObject *self, PyObject *v)
"No __add__ or __concat__ methods, or maybe I'm just being stupid."
);
return
NULL
;
}
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
concat_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
UNLESS_ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_concat
(
self
,
v
))
return
NULL
;
}
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_concat
(
self
,
v
));
else
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
self
,
v
));
else
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
v
))
return
NULL
;
}
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
v
));
return
m
;
}
...
...
@@ -2092,14 +2215,11 @@ subclass_repeat(PyObject *self, int v)
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__repeat__
))
return
NULL
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
repeat_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
UNLESS_ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_repeat
(
self
,
v
))
return
NULL
;
}
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_repeat
(
self
,
v
));
else
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"Oi"
,
self
,
v
));
else
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"i"
,
v
))
return
NULL
;
}
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"i"
,
v
));
return
m
;
}
...
...
@@ -2131,20 +2251,30 @@ subclass_subscript(PyObject *self, PyObject *key)
return
t
->
tp_as_mapping
->
mp_subscript
(
self
,
key
);
}
}
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
key
))
goto
err
;
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
self
,
key
));
else
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
key
));
return
m
;
err:
Py_DECREF
(
m
);
return
NULL
;
}
static
long
subclass_ass_subscript
(
PyObject
*
self
,
PyObject
*
index
,
PyObject
*
v
)
{
long
r
;
PyObject
*
m
;
PyExtensionClass
*
t
;
if
(
!
v
&&
(
m
=
subclass_getspecial
(
self
,
py__delitem__
)))
{
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
self
,
index
))
return
-
1
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
index
))
return
-
1
;
Py_DECREF
(
m
);
return
0
;
}
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__setitem__
))
return
-
1
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
setitem_by_name
...
...
@@ -2157,13 +2287,18 @@ subclass_ass_subscript(PyObject *self, PyObject *index, PyObject *v)
return
t
->
tp_as_mapping
->
mp_ass_subscript
(
self
,
index
,
v
);
}
}
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
index
,
v
))
return
-
1
;
r
=
PyInt_AsLong
(
m
);
Py_DECREF
(
m
);
return
r
;
err:
if
(
!
v
)
{
PyErr_SetObject
(
PyExc_AttributeError
,
py__delitem__
);
return
-
1
;
}
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OOO"
,
self
,
index
,
v
))
return
-
1
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
index
,
v
))
return
-
1
;
Py_DECREF
(
m
);
return
NULL
;
return
0
;
}
PyMappingMethods
subclass_as_mapping
=
{
...
...
@@ -2182,11 +2317,11 @@ dealloc_base(PyObject *inst, PyExtensionClass* self)
for
(
i
=
0
;
i
<
l
;
i
++
)
{
t
=
PyTuple_GET_ITEM
(
self
->
bases
,
i
);
if
(
Py
ExtensionClass_Check
(
t
))
if
(
ExtensionClass_Check
(
t
))
{
if
(
As
Py
ExtensionClass
(
t
)
->
bases
)
if
(
AsExtensionClass
(
t
)
->
bases
)
{
if
(
dealloc_base
(
inst
,
As
Py
ExtensionClass
(
t
)))
return
1
;
if
(
dealloc_base
(
inst
,
AsExtensionClass
(
t
)))
return
1
;
}
else
{
...
...
@@ -2206,11 +2341,29 @@ subclass_dealloc(PyObject *self)
{
PyObject
*
m
,
*
t
,
*
v
,
*
tb
;
#ifdef TRACE_DEALLOC
fprintf
(
stderr
,
"Deallocating a %s
\n
"
,
self
->
ob_type
->
tp_name
);
#endif
PyErr_Fetch
(
&
t
,
&
v
,
&
tb
);
Py_INCREF
(
self
);
/* Give us a new lease on life */
if
(
m
=
subclass_getspecial
(
self
,
py__del__
))
PyObject_CallFunction
(
m
,
""
);
{
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
self
));
else
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
""
));
Py_XDECREF
(
m
);
}
PyErr_Clear
();
if
(
--
self
->
ob_refcnt
>
0
)
{
PyErr_Restore
(
t
,
v
,
tb
);
return
;
/* we added a reference; don't delete now */
}
Py_XDECREF
(
INSTANCE_DICT
(
self
));
Py_DECREF
(
self
->
ob_type
);
...
...
@@ -2220,41 +2373,53 @@ subclass_dealloc(PyObject *self)
PyErr_Restore
(
t
,
v
,
tb
);
}
static
int
datafull_baseclasses
(
PyExtensionClass
*
type
)
static
void
datafull_baseclasses
f
(
PyExtensionClass
*
type
,
PyObject
**
c1
,
PyObject
**
c2
)
{
/* Find the number of classes that have data and return them.
There should be
only
one.
There should be
no more than
one.
*/
int
l
,
i
,
n
=
0
;
PyObject
*
base
;
typedef
struct
{
PyObject_HEAD
}
Dataless
;
l
=
PyTuple_Size
(
type
->
bases
);
for
(
i
=
0
;
i
<
l
;
i
++
)
for
(
i
=
0
;
i
<
l
&&
!
(
*
c1
&&
*
c2
)
;
i
++
)
{
base
=
PyTuple_GET_ITEM
(
type
->
bases
,
i
);
if
(
Py
ExtensionClass_Check
(
base
))
if
(
ExtensionClass_Check
(
base
))
{
if
(
As
Py
ExtensionClass
(
base
)
->
bases
)
n
+=
datafull_baseclasses
(
AsPyExtensionClass
(
base
)
);
if
(
AsExtensionClass
(
base
)
->
bases
)
datafull_baseclassesf
(
AsExtensionClass
(
base
),
c1
,
c2
);
else
{
if
(
AsPyExtensionClass
(
base
)
->
tp_basicsize
>
sizeof
(
Dataless
)
||
AsPyExtensionClass
(
base
)
->
tp_itemsize
>
0
)
n
++
;
if
(
AsExtensionClass
(
base
)
->
tp_basicsize
>
sizeof
(
PyPureMixinObject
)
||
AsExtensionClass
(
base
)
->
tp_itemsize
>
0
)
{
if
(
!
*
c1
)
*
c1
=
base
;
else
if
(
*
c1
!=
base
)
*
c2
=
base
;
}
}
}
}
return
n
;
}
static
int
datafull_baseclasses
(
PyExtensionClass
*
type
)
{
PyObject
*
c1
=
0
,
*
c2
=
0
;
datafull_baseclassesf
(
type
,
&
c1
,
&
c2
);
if
(
c2
)
return
2
;
if
(
c1
)
return
1
;
return
0
;
}
static
PyObject
*
datafull_baseclass
(
PyExtensionClass
*
type
)
{
/* Find the number of classes that have data and return them.
There should be only one.
*/
/* Find the baseclass that has data and. There should be only one. */
int
l
,
i
,
n
=
0
;
PyObject
*
base
,
*
dbase
;
...
...
@@ -2262,17 +2427,18 @@ datafull_baseclass(PyExtensionClass *type)
for
(
i
=
0
;
i
<
l
;
i
++
)
{
base
=
PyTuple_GET_ITEM
(
type
->
bases
,
i
);
if
(
Py
ExtensionClass_Check
(
base
))
if
(
ExtensionClass_Check
(
base
))
{
if
(
As
Py
ExtensionClass
(
base
)
->
bases
)
if
(
AsExtensionClass
(
base
)
->
bases
)
{
if
(
dbase
=
datafull_baseclass
(
As
Py
ExtensionClass
(
base
)))
if
(
dbase
=
datafull_baseclass
(
AsExtensionClass
(
base
)))
return
dbase
;
}
else
{
if
(
AsPyExtensionClass
(
base
)
->
tp_basicsize
>
sizeof
(
Dataless
)
||
AsPyExtensionClass
(
base
)
->
tp_itemsize
>
0
)
if
(
AsExtensionClass
(
base
)
->
tp_basicsize
>
sizeof
(
PyPureMixinObject
)
||
AsExtensionClass
(
base
)
->
tp_itemsize
>
0
)
return
base
;
}
}
...
...
@@ -2280,6 +2446,23 @@ datafull_baseclass(PyExtensionClass *type)
return
NULL
;
}
static
PyObject
*
extension_baseclass
(
PyExtensionClass
*
type
)
{
/* Find the first immediate base class that is an extension class */
int
l
,
i
,
n
=
0
;
PyObject
*
base
;
l
=
PyTuple_Size
(
type
->
bases
);
for
(
i
=
0
;
i
<
l
;
i
++
)
{
base
=
PyTuple_GET_ITEM
(
type
->
bases
,
i
);
if
(
ExtensionClass_Check
(
base
))
return
base
;
}
return
PyErr_Format
(
PyExc_TypeError
,
"No extension class found in subclass"
,
NULL
);
}
static
int
subclass_hasattr
(
PyExtensionClass
*
type
,
PyObject
*
name
)
{
...
...
@@ -2341,38 +2524,29 @@ subclass_init_getattr(PyExtensionClass *self, PyObject *methods)
{
PyObject
*
m
;
if
((
m
=
CCL_getattr
(
self
,
py__getattr__
,
"__getattr__"
)))
if
((
m
=
CCL_getattr
(
self
,
py__getattr__
,
0
)))
{
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
getattr_by_name
&&
Subclass_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
self
->
tp_getattr
=
AsCMethod
(
m
)
->
type
->
tp_getattr
;
}
#if PYTHON_API_VERSION >= 1005
else
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
getattro_by_name
&&
Subclass_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
self
->
tp_getattro
=
AsCMethod
(
m
)
->
type
->
tp_getattro
;
}
#endif
else
{
PyDict_SetItem
(
methods
,
py__getattr__
,
m
);
#if PYTHON_API_VERSION >= 1005
PyObject_SetItem
(
methods
,
py__getattr__
,
m
);
self
->
tp_getattro
=
subclass_getattro
;
#else
self
->
tp_getattr
=
subclass_getattr
;
#endif
}
Py_DECREF
(
m
);
}
else
{
PyErr_Clear
();
#if PYTHON_API_VERSION >= 1005
self
->
tp_getattro
=
EC_findiattro
;
#else
self
->
tp_getattr
=
EC_findiattrs
;
#endif
}
}
...
...
@@ -2381,41 +2555,58 @@ subclass_init_setattr(PyExtensionClass *self, PyObject *methods)
{
PyObject
*
m
;
if
((
m
=
CCL_getattr
(
self
,
py__setattr__
,
"__setattr__"
)))
if
((
m
=
CCL_getattr
(
self
,
py__setattr__
,
0
)))
{
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
setattr_by_name
&&
Subclass_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
self
->
tp_setattr
=
AsCMethod
(
m
)
->
type
->
tp_setattr
;
}
#if PYTHON_API_VERSION >= 1005
else
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
setattro_by_name
&&
Subclass_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
self
->
tp_setattro
=
AsCMethod
(
m
)
->
type
->
tp_setattro
;
}
#endif
else
{
PyDict_SetItem
(
methods
,
py__setattr__
,
m
);
#if PYTHON_API_VERSION >= 1005
PyObject_SetItem
(
methods
,
py__setattr__
,
m
);
self
->
tp_setattro
=
subclass_setattro
;
#else
self
->
tp_setattr
=
subclass_setattr
;
#endif
}
Py_DECREF
(
m
);
}
else
{
PyErr_Clear
();
#if PYTHON_API_VERSION >= 1005
self
->
tp_setattro
=
subclass_simple_setattro
;
#else
self
->
tp_setattro
=
subclass_simple_setattr
;
#endif
}
}
static
PyObject
*
CopyMethods
(
PyExtensionClass
*
type
,
PyObject
*
base_methods
)
{
PyObject
*
methods
,
*
key
,
*
v
;
int
pos
;
UNLESS
(
type
->
class_dictionary
&&
PyDict_Check
(
base_methods
)
&&
ExtensionInstance_Check
(
type
->
class_dictionary
))
{
Py_INCREF
(
base_methods
);
return
base_methods
;
}
UNLESS
(
methods
=
PyObject_CallObject
((
PyObject
*
)
type
->
class_dictionary
->
ob_type
,
NULL
))
return
NULL
;
for
(
pos
=
0
;
PyDict_Next
(
base_methods
,
&
pos
,
&
key
,
&
v
);
)
UNLESS
(
0
<=
PyObject_SetItem
(
methods
,
key
,
v
))
goto
err
;
return
methods
;
err:
Py_DECREF
(
methods
);
return
NULL
;
}
/* Constructor for building subclasses of C classes.
...
...
@@ -2427,10 +2618,14 @@ subclass__init__(PyExtensionClass *self, PyObject *args)
{
PyObject
*
bases
,
*
methods
,
*
class_init
;
PyExtensionClass
*
type
;
char
*
name
;
int
dynamic
=
1
;
char
*
name
,
*
p
;
int
dynamic
=
1
,
l
;
UNLESS
(
PyArg_Parse
(
args
,
"(sOO)"
,
&
name
,
&
bases
,
&
methods
))
return
NULL
;
l
=
strlen
(
name
)
+
1
;
UNLESS
(
p
=
(
char
*
)
malloc
(
l
*
sizeof
(
char
)))
return
PyErr_NoMemory
();
memcpy
(
p
,
name
,
l
);
name
=
p
;
UNLESS
(
PyTuple_Check
(
bases
)
&&
PyTuple_Size
(
bases
))
{
...
...
@@ -2448,12 +2643,13 @@ subclass__init__(PyExtensionClass *self, PyObject *args)
return
NULL
;
}
UNLESS
(
type
=
(
PyExtensionClass
*
)
datafull_baseclass
(
self
))
type
=
(
PyExtensionClass
*
)
PyTuple_GET_ITEM
(
bases
,
0
);
UNLESS
(
type
=
(
PyExtensionClass
*
)
extension_baseclass
(
self
))
return
NULL
;
self
->
tp_name
=
name
;
self
->
bases
=
bases
;
Py_INCREF
(
methods
)
;
self
->
class_dictionary
=
methods
;
UNLESS
(
self
->
class_dictionary
=
CopyMethods
(
type
,
methods
))
return
NULL
;
#define copy_member(M) self->M=type->M
copy_member
(
ob_size
);
copy_member
(
class_flags
);
...
...
@@ -2481,19 +2677,28 @@ subclass__init__(PyExtensionClass *self, PyObject *args)
subclass_set
(
compare
,
cmp
);
subclass_set
(
repr
,
repr
);
if
(
subclass_hasattr
(
self
,
py__bind_to_object__
)
&&
subclass_hasattr
(
self
,
py__call__
))
if
(
subclass_hasattr
(
self
,
py__of__
))
self
->
class_flags
|=
EXTENSIONCLASS_BINDABLE_FLAG
;
if
(
dynamic
||
has_number_methods
(
self
))
self
->
tp_as_number
=&
subclass_as_number
;
{
self
->
tp_as_number
=
(
PyNumberMethods
*
)
malloc
(
sizeof
(
PyNumberMethods
));
UNLESS
(
self
->
tp_as_number
)
return
PyErr_NoMemory
();
*
(
self
->
tp_as_number
)
=
subclass_as_number
;
}
else
self
->
tp_as_number
=
NULL
;
if
(
dynamic
||
has_collection_methods
(
self
))
{
self
->
tp_as_sequence
=&
subclass_as_sequence
;
self
->
tp_as_mapping
=&
subclass_as_mapping
;
self
->
tp_as_sequence
=
(
PySequenceMethods
*
)
malloc
(
sizeof
(
PySequenceMethods
));
UNLESS
(
self
->
tp_as_sequence
)
return
PyErr_NoMemory
();
*
(
self
->
tp_as_sequence
)
=
subclass_as_sequence
;
self
->
tp_as_mapping
=
(
PyMappingMethods
*
)
malloc
(
sizeof
(
PyMappingMethods
));
UNLESS
(
self
->
tp_as_mapping
)
return
PyErr_NoMemory
();
*
(
self
->
tp_as_mapping
)
=
subclass_as_mapping
;
}
else
{
...
...
@@ -2506,11 +2711,9 @@ subclass__init__(PyExtensionClass *self, PyObject *args)
self
->
tp_doc
=
0
;
/* Check for and use __class_init__ */
if
(
class_init
=
PyObject_GetAttrString
(
AsPyObject
(
self
),
"
__class
_init__"
))
if
(
class_init
=
PyObject_GetAttrString
(
AsPyObject
(
self
),
"
class_
_init__"
))
{
UNLESS_ASSIGN
(
class_init
,
PyObject_GetAttrString
(
class_init
,
"im_func"
))
return
NULL
;
UNLESS_ASSIGN
(
class_init
,
PyObject_CallFunction
(
class_init
,
"O"
,
self
))
UNLESS_ASSIGN
(
class_init
,
PyObject_CallObject
(
class_init
,
NULL
))
return
NULL
;
Py_DECREF
(
class_init
);
}
...
...
@@ -2527,18 +2730,17 @@ struct PyMethodDef ExtensionClass_methods[] = {
{
NULL
,
NULL
}
/* sentinel */
};
static
PyExtensionClass
CCLtype
=
{
PyObject_HEAD_INIT
(
&
CCLtype_class
)
static
PyExtensionClass
ECType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"
C Class"
,
/*tp_name*/
"
ExtensionClass"
,
/*tp_name*/
sizeof
(
PyExtensionClass
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
CCL_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
CCL_getattrs
,
/*tp_getattr*/
(
setattrfunc
)
CCL_setattrs
,
/*tp_setattr*/
(
getattrfunc
)
0
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
CCL_repr
,
/*tp_repr*/
0
,
/*tp_as_number*/
...
...
@@ -2547,149 +2749,50 @@ static PyExtensionClass CCLtype = {
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
CCL_call
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
#if PYTHON_API_VERSION >= 1005
(
getattrofunc
)
CCL_getattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
CCL_setattro
,
/*tp_setattr with object key*/
#else
/* Space for future expansion */
0L
,
0L
,
#endif
0L
,
0L
,
"C classes"
,
/* Documentation string */
METHOD_CHAIN
(
ExtensionClass_methods
)
};
static
PyExtensionClass
Basetype
=
{
PyObject_HEAD_INIT
(
&
PyType_Type
)
0
,
/*ob_size*/
"Base"
,
/*tp_name*/
sizeof
(
Dataless
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
0
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
EC_findiattrs
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
0
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
#if PYTHON_API_VERSION >= 1005
(
getattrofunc
)
EC_findiattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
0
,
/*tp_setattr with object key*/
#else
/* Space for future expansion */
0L
,
0L
,
#endif
0L
,
0L
,
"Base -- a do nothing base class
\n
"
"
\n
"
"A trivial base class that doesn't have any inheritable
\n
"
"attributes but that can be listed first in the set of superclasses
\n
"
"of a new subclass.
\n
"
,
{
NULL
,
NULL
}
};
static
PyObject
*
bind_to_object
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
inst
;
PMethod
*
r
;
UNLESS
(
PyArg_Parse
(
args
,
"O"
,
&
inst
))
return
NULL
;
UNLESS
(
PyExtensionInstance_Check
(
inst
))
{
PyErr_SetString
(
PyExc_TypeError
,
"attempt to wrap extension method using an object that
\n
"
"is not an extension class instance."
);
return
NULL
;
}
UNLESS
(
r
=
PyObject_NEW
(
PMethod
,
&
PMethodType
))
return
NULL
;
Py_INCREF
(
inst
);
Py_INCREF
(
inst
->
ob_type
);
r
->
type
=
inst
->
ob_type
;
r
->
self
=
inst
;
r
->
meth
=
self
;
return
AsPyObject
(
r
);
}
struct
PyMethodDef
Method_methods
[]
=
{
{
"__bind_to_object__"
,(
PyCFunction
)
bind_to_object
,
0
,
""
},
{
NULL
,
NULL
}
/* sentinel */
};
static
PyExtensionClass
Methodtype
=
{
PyObject_HEAD_INIT
(
&
PyType_Type
)
0
,
/*ob_size*/
"Method"
,
/*tp_name*/
sizeof
(
Dataless
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
0
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
EC_findiattrs
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
0
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
#if PYTHON_API_VERSION >= 1005
(
getattrofunc
)
EC_findiattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
0
,
/*tp_setattr with object key*/
#else
/* Space for future expansion */
0L
,
0L
,
#endif
0L
,
0L
,
"Base class for objects that want to be treated as methods
\n
"
"
\n
"
"The method class provides a method, __bind_to_object__, that
\n
"
"binds an object to an instance. If a method is a subobject
\n
"
"of an extension-class instance, the the method will be bound
\n
"
"to the instance and when the resulting object is called, it
\n
"
"will call the method and pass the instance in addition to
\n
"
"other arguments. It is the responsibility of Method objects
\n
"
"to implement (or inherit) a __call__ method.
\n
"
,
METHOD_CHAIN
(
Method_methods
)
};
PyObject
*
MetaTypeUndefinedMethod
()
{
PyErr_SetString
(
PyExc_TypeError
,
"undefined operation on partially numeric PyObject"
);
return
NULL
;
}
/* List of methods defined in the module */
static
struct
PyMethodDef
CC_methods
[]
=
{
{
NULL
,
NULL
}
/* sentinel */
{
NULL
,
NULL
}
/* sentinel */
};
static
int
export_type
(
PyObject
*
dict
,
char
*
name
,
PyExtensionClass
*
typ
)
{
initializeBaseExtensionClass
(
typ
);
return
PyMapping_SetItemString
(
dict
,
name
,(
PyObject
*
)
typ
);
}
static
struct
ExtensionClassCAPIstruct
TrueExtensionClassCAPI
=
{
export_type
,
EC_findiattrs
,
EC_findiattro
,
subclass_simple_setattr
,
subclass_simple_setattro
,
(
PyObject
*
)
&
ECType
,
(
PyObject
*
)
&
PMethodType
,
PMethod_New
,
};
void
initExtensionClass
()
{
PyObject
*
m
,
*
d
;
PURE_MIXIN_CLASS
(
Base
,
"Minimalbase class for Extension Classes"
,
NULL
);
PMethodType
.
ob_type
=&
PyType_Type
;
CMethodType
.
ob_type
=&
PyType_Type
;
ECTypeType
.
ob_type
=&
PyType_Type
;
ECType
.
ob_type
=&
ECTypeType
;
/* Create the module and add the functions */
m
=
Py_InitModule4
(
"ExtensionClass"
,
CC_methods
,
ExtensionClass_module_documentation
,
...
...
@@ -2700,28 +2803,19 @@ initExtensionClass()
init_py_names
();
initializeBaseExtensionClass
(
&
CCLt
ype
);
PyDict_SetItemString
(
d
,
"ExtensionClass
Type"
,
(
PyObject
*
)
&
CCLt
ype
);
initializeBaseExtensionClass
(
&
ECT
ype
);
PyDict_SetItemString
(
d
,
"ExtensionClass
"
,
(
PyObject
*
)
&
ECT
ype
);
initializeBaseExtensionClass
(
&
Base
t
ype
);
PyDict_SetItemString
(
d
,
"Base"
,
(
PyObject
*
)
&
Base
t
ype
);
initializeBaseExtensionClass
(
&
Base
T
ype
);
PyDict_SetItemString
(
d
,
"Base"
,
(
PyObject
*
)
&
Base
T
ype
);
initializeBaseExtensionClass
(
&
Methodt
ype
);
PyDict_SetItemString
(
d
,
"
Method"
,
(
PyObject
*
)
&
Methodt
ype
);
PyDict_SetItemString
(
d
,
"PythonMethodType"
,
(
PyObject
*
)
&
PMethodT
ype
);
PyDict_SetItemString
(
d
,
"
ExtensionMethodType"
,
(
PyObject
*
)
&
CMethodT
ype
);
#ifdef Py_COBJECT_H
/* Export C attribute lookup API */
PyDict_SetItemString
(
d
,
"_PyEC_getattrs"
,
PyCObject_FromVoidPtr
(
EC_findiattrs
,
NULL
));
PyDict_SetItemString
(
d
,
"_PyEC_getattro"
,
PyCObject_FromVoidPtr
(
EC_findiattro
,
NULL
));
PyDict_SetItemString
(
d
,
"_PyEC_setattrs"
,
PyCObject_FromVoidPtr
(
subclass_simple_setattr
,
NULL
));
PyDict_SetItemString
(
d
,
"_PyEC_setattro"
,
PyCObject_FromVoidPtr
(
subclass_simple_setattro
,
NULL
));
#endif
PyExtensionClassCAPI
=&
TrueExtensionClassCAPI
;
PyDict_SetItemString
(
d
,
"CAPI"
,
PyCObject_FromVoidPtr
(
PyExtensionClassCAPI
,
NULL
));
/* Check for errors */
if
(
PyErr_Occurred
())
Py_FatalError
(
"can't initialize module ExtensionClass"
);
CHECK_FOR_ERRORS
(
"can't initialize module ExtensionClass"
);
}
lib/Components/ExtensionClass/src/ExtensionClass.c
View file @
959a884e
/*
$Id: ExtensionClass.c,v 1.
4 1996/12/06 17:12:29
jim Exp $
$Id: ExtensionClass.c,v 1.
5 1997/02/17 16:27:53
jim Exp $
Extension Class
...
...
@@ -56,6 +56,9 @@
(540) 371-6909
$Log: ExtensionClass.c,v $
Revision 1.5 1997/02/17 16:27:53 jim
Many changes.
Revision 1.4 1996/12/06 17:12:29 jim
Major speed enhancements for attribute lookup and calling special
methods.
...
...
@@ -88,40 +91,56 @@ static char ExtensionClass_module_documentation[] =
" - They provide access to unbound methods,
\n
"
" - They can be called to create instances.
\n
"
"
\n
"
"$Id: ExtensionClass.c,v 1.
4 1996/12/06 17:12:29
jim Exp $
\n
"
"$Id: ExtensionClass.c,v 1.
5 1997/02/17 16:27:53
jim Exp $
\n
"
;
#include <stdio.h>
#include "Python.h"
#include "PyErr_Format.c"
static
void
PyVar_Assign
(
PyObject
**
v
,
PyObject
*
e
)
{
Py_XDECREF
(
*
v
);
*
v
=
e
;
}
#define ASSIGN(V,E)
{PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define ASSIGN(V,E)
PyVar_Assign(&(V),(E))
#define UNLESS(E) if(!(E))
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E) UNLESS(V)
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E)
;
UNLESS(V)
#define INSTANCE_DICT(inst) \
*(((PyObject**)inst) + (inst->ob_type->tp_basicsize/sizeof(PyObject*) - 1))
typedef
struct
{
PyObject_HEAD
}
Dataless
;
/* Declarations for objects of type ExtensionClass */
#include "ExtensionClass.h"
staticforward
PyExtensionClass
CCLtype
;
#define PyExtensionClass_Check(O) ((O)->ob_type == (PyTypeObject*)&CCLtype)
#define PyExtensionInstance_Check(O) \
((O)->ob_type->ob_type == (PyTypeObject*)&CCLtype)
#define AsPyExtensionClass(O) ((PyExtensionClass*)(O))
#define PyExtensionClassOf(O) ((PyExtensionClass*)((O)->ob_type))
staticforward
PyExtensionClass
ECType
;
#define ExtensionClass_Check(O) ((O)->ob_type == (PyTypeObject*)&ECType)
#define ExtensionInstance_Check(O) \
((O)->ob_type->ob_type == (PyTypeObject*)&ECType)
#define AsExtensionClass(O) ((PyExtensionClass*)(O))
#define ExtensionClassOf(O) ((PyExtensionClass*)((O)->ob_type))
#define AsPyObject(O) ((PyObject*)(O))
#define NeedsToBeBound(O) \
((O)->ob_type->ob_type == (PyTypeObject*)&ECType && \
(((PyExtensionClass*)((O)->ob_type))->class_flags & \
EXTENSIONCLASS_BINDABLE_FLAG))
static
PyObject
*
py__add__
,
*
py__sub__
,
*
py__mul__
,
*
py__div__
,
*
py__mod__
,
*
py__pow__
,
*
py__divmod__
,
*
py__lshift__
,
*
py__rshift__
,
*
py__and__
,
*
py__or__
,
*
py__xor__
,
*
py__coerce__
,
*
py__neg__
,
*
py__pos__
,
*
py__abs__
,
*
py__nonzero__
,
*
py__inv__
,
*
py__int__
,
*
py__long__
,
*
py__float__
,
*
py__oct__
,
*
py__hex__
,
*
py__getitem__
,
*
py__setitem__
,
*
py__getslice__
,
*
py__setslice__
,
*
py__concat__
,
*
py__repeat__
,
*
py__len__
,
*
py__bind_to_object__
,
*
py__call__
,
*
py__getattr__
,
*
py__setattr__
,
*
py__del__
,
*
py__repr__
,
*
py__str__
,
*
py__hash__
,
*
py__cmp__
,
*
py__var_size__
,
*
py__init__
;
*
py__long__
,
*
py__float__
,
*
py__oct__
,
*
py__hex__
,
*
py__getitem__
,
*
py__setitem__
,
*
py__delitem__
,
*
py__getslice__
,
*
py__setslice__
,
*
py__delslice__
,
*
py__concat__
,
*
py__repeat__
,
*
py__len__
,
*
py__of__
,
*
py__call__
,
*
py__getattr__
,
*
py__setattr__
,
*
py__delattr__
,
*
py__del__
,
*
py__repr__
,
*
py__str__
,
*
py__class__
,
*
py__hash__
,
*
py__cmp__
,
*
py__var_size__
,
*
py__init__
,
*
py__getinitargs__
,
*
py__getstate__
,
*
py__setstate__
,
*
py__dict__
,
*
pyclass_
;
static
void
init_py_names
()
...
...
@@ -152,26 +171,48 @@ init_py_names()
INIT_PY_NAME
(
__hex__
);
INIT_PY_NAME
(
__getitem__
);
INIT_PY_NAME
(
__setitem__
);
INIT_PY_NAME
(
__delitem__
);
INIT_PY_NAME
(
__getslice__
);
INIT_PY_NAME
(
__setslice__
);
INIT_PY_NAME
(
__delslice__
);
INIT_PY_NAME
(
__concat__
);
INIT_PY_NAME
(
__repeat__
);
INIT_PY_NAME
(
__len__
);
INIT_PY_NAME
(
__
bind_to_object
__
);
INIT_PY_NAME
(
__
of
__
);
INIT_PY_NAME
(
__call__
);
INIT_PY_NAME
(
__getattr__
);
INIT_PY_NAME
(
__setattr__
);
INIT_PY_NAME
(
__delattr__
);
INIT_PY_NAME
(
__del__
);
INIT_PY_NAME
(
__repr__
);
INIT_PY_NAME
(
__str__
);
INIT_PY_NAME
(
__class__
);
INIT_PY_NAME
(
__hash__
);
INIT_PY_NAME
(
__cmp__
);
INIT_PY_NAME
(
__var_size__
);
INIT_PY_NAME
(
__init__
);
INIT_PY_NAME
(
__getinitargs__
);
INIT_PY_NAME
(
__getstate__
);
INIT_PY_NAME
(
__setstate__
);
INIT_PY_NAME
(
__dict__
);
INIT_PY_NAME
(
class_
);
#undef INIT_PY_NAME
}
static
PyObject
*
CallMethodO
(
PyObject
*
self
,
PyObject
*
name
,
PyObject
*
args
,
PyObject
*
kw
)
{
if
(
!
args
&&
PyErr_Occurred
())
return
NULL
;
UNLESS
(
name
=
PyObject_GetAttr
(
self
,
name
))
return
NULL
;
ASSIGN
(
name
,
PyEval_CallObjectWithKeywords
(
name
,
args
,
kw
));
if
(
args
)
Py_DECREF
(
args
);
return
name
;
}
#define Build Py_BuildValue
/* CMethod objects: */
typedef
struct
{
...
...
@@ -204,9 +245,9 @@ CMethod_issubclass(PyExtensionClass *sub, PyExtensionClass *type)
{
t
=
PyTuple_GET_ITEM
(
sub
->
bases
,
i
);
if
(
t
==
(
PyObject
*
)
type
)
return
1
;
if
(
Py
ExtensionClass_Check
(
t
)
&&
As
Py
ExtensionClass
(
t
)
->
bases
&&
CMethod_issubclass
(
As
Py
ExtensionClass
(
t
),
type
)
if
(
ExtensionClass_Check
(
t
)
&&
AsExtensionClass
(
t
)
->
bases
&&
CMethod_issubclass
(
AsExtensionClass
(
t
),
type
)
)
return
1
;
}
return
0
;
...
...
@@ -220,8 +261,8 @@ CMethod_issubclass(PyExtensionClass *sub, PyExtensionClass *type)
(PyExtensionClass *)(C2))
static
CMethod
*
newCMethod
(
Py
TypeObject
*
type
,
static
PyObject
*
newCMethod
(
Py
ExtensionClass
*
type
,
PyObject
*
inst
,
char
*
name
,
PyCFunction
meth
,
int
flags
,
char
*
doc
)
{
CMethod
*
self
;
...
...
@@ -229,13 +270,14 @@ newCMethod(PyTypeObject *type,
UNLESS
(
self
=
PyObject_NEW
(
CMethod
,
&
CMethodType
))
return
NULL
;
Py_INCREF
(
type
);
self
->
type
=
type
;
self
->
self
=
NULL
;
Py_XINCREF
(
inst
);
self
->
type
=
(
PyTypeObject
*
)
type
;
self
->
self
=
inst
;
self
->
name
=
name
;
self
->
meth
=
meth
;
self
->
flags
=
flags
;
self
->
doc
=
doc
;
return
self
;
return
(
PyObject
*
)
self
;
}
static
CMethod
*
...
...
@@ -244,7 +286,7 @@ bindCMethod(CMethod *m, PyObject *inst)
CMethod
*
self
;
UNLESS
(
inst
->
ob_type
==
m
->
type
||
(
Py
ExtensionInstance_Check
(
inst
)
(
ExtensionInstance_Check
(
inst
)
&&
SubclassInstance_Check
(
inst
,
m
->
type
))
)
{
...
...
@@ -268,7 +310,10 @@ bindCMethod(CMethod *m, PyObject *inst)
static
void
CMethod_dealloc
(
CMethod
*
self
)
{
Py_DECREF
(
self
->
type
);
#ifdef TRACE_DEALLOC
fprintf
(
stderr
,
"Deallocating C method %s
\n
"
,
self
->
name
);
#endif
Py_XDECREF
(
self
->
type
);
Py_XDECREF
(
self
->
self
);
PyMem_DEL
(
self
);
}
...
...
@@ -297,13 +342,10 @@ call_cmethod(CMethod *self, PyObject *inst, PyObject *args, PyObject *kw)
}
}
static
PyObject
*
CMethod_call
(
CMethod
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
int
size
;
char
*
buf
;
PyObject
*
s
;
if
(
self
->
self
)
return
call_cmethod
(
self
,
self
->
self
,
args
,
kw
);
...
...
@@ -313,29 +355,23 @@ CMethod_call(CMethod *self, PyObject *args, PyObject *kw)
UNLESS
(
first
=
PyTuple_GET_ITEM
(
args
,
0
))
return
NULL
;
if
(
first
->
ob_type
==
self
->
type
||
(
Py
ExtensionInstance_Check
(
first
)
(
ExtensionInstance_Check
(
first
)
&&
CMethod_issubclass
(
Py
ExtensionClassOf
(
first
),
As
Py
ExtensionClass
(
self
->
type
))
CMethod_issubclass
(
ExtensionClassOf
(
first
),
AsExtensionClass
(
self
->
type
))
)
);
{
PyObject
*
rest
=
0
;
UNLESS
(
rest
=
PySequence_GetSlice
(
args
,
1
,
size
))
return
NULL
;
return
call_cmethod
(
self
,
first
,
rest
,
kw
);
ASSIGN
(
rest
,
call_cmethod
(
self
,
first
,
rest
,
kw
));
return
rest
;
}
}
/* Call of unbound method without instance argument */
size
=
strlen
(
self
->
type
->
tp_name
);
UNLESS
(
s
=
PyString_FromStringAndSize
(
NULL
,
size
+
48
))
return
NULL
;
buf
=
PyString_AsString
(
s
);
sprintf
(
buf
,
"unbound C method must be called with %s 1st argument"
,
self
->
type
->
tp_name
);
PyErr_SetObject
(
PyExc_TypeError
,
s
);
Py_DECREF
(
s
);
return
NULL
;
return
PyErr_Format
(
PyExc_TypeError
,
"unbound C method must be called with %s 1st argument"
,
"s"
,
self
->
type
->
tp_name
);
}
static
PyObject
*
...
...
@@ -372,42 +408,39 @@ CMethod_getattr(CMethod *self, char *name)
Py_INCREF
(
r
);
return
r
;
}
PyErr_SetString
(
PyExc_AttributeError
,
name
);
return
NULL
;
}
static
PyTypeObject
CMethodType
=
{
PyObject_HEAD_INIT
(
&
PyType_Type
)
0
,
/*ob_size*/
"CMethod"
,
/*tp_name*/
sizeof
(
CMethod
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
CMethod_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
CMethod_getattr
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
CMethod_call
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
/* Space for future expansion */
0L
,
0L
,
0L
,
0L
,
"Storage manager for unbound C function PyObject data"
/* Documentation string */
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"CMethod"
,
/*tp_name*/
sizeof
(
CMethod
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
CMethod_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
CMethod_getattr
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
CMethod_call
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
/* Space for future expansion */
0L
,
0L
,
0L
,
0L
,
"Storage manager for unbound C function PyObject data"
/* Documentation string */
};
/* PMethod objects: */
typedef
struct
{
PyObject_HEAD
PyTypeObject
*
type
;
PyObject
*
self
;
PyObject
*
meth
;
}
PMethod
;
#define PMethod PyECMethodObject
staticforward
PyTypeObject
PMethodType
;
...
...
@@ -420,31 +453,33 @@ staticforward PyTypeObject PMethodType;
&& ! ((PMethod*)(O))->self)
static
P
Method
*
newPMethod
(
Py
TypeObject
*
type
,
PyObject
*
meth
)
static
P
yObject
*
newPMethod
(
Py
ExtensionClass
*
type
,
PyObject
*
meth
)
{
PMethod
*
self
;
UNLESS
(
self
=
PyObject_NEW
(
PMethod
,
&
PMethodType
))
return
NULL
;
Py_INCREF
(
type
);
Py_INCREF
(
meth
);
self
->
type
=
type
;
self
->
type
=
(
PyTypeObject
*
)
type
;
self
->
self
=
NULL
;
self
->
meth
=
meth
;
return
self
;
return
(
PyObject
*
)
self
;
}
static
P
Method
*
static
P
yObject
*
bindPMethod
(
PMethod
*
m
,
PyObject
*
inst
)
{
PMethod
*
self
;
UNLESS
(
PyExtensionInstance_Check
(
inst
))
if
(
NeedsToBeBound
(
m
->
meth
))
return
CallMethodO
(
m
->
meth
,
py__of__
,
Build
(
"(O)"
,
inst
),
NULL
);
if
(
m
->
ob_refcnt
==
1
)
{
Py
Err_SetString
(
PyExc_TypeError
,
"attempt to wrap extension method using an object that
\n
"
"is not an extension class instance."
);
return
NULL
;
Py
_INCREF
(
inst
);
ASSIGN
(
m
->
self
,
inst
);
Py_INCREF
(
m
);
return
(
PyObject
*
)
m
;
}
UNLESS
(
self
=
PyObject_NEW
(
PMethod
,
&
PMethodType
))
return
NULL
;
...
...
@@ -454,15 +489,36 @@ bindPMethod(PMethod *m, PyObject *inst)
self
->
type
=
m
->
type
;
self
->
self
=
inst
;
self
->
meth
=
m
->
meth
;
return
self
;
return
(
PyObject
*
)
self
;
}
static
PyObject
*
PMethod_New
(
PyObject
*
meth
,
PyObject
*
inst
)
{
if
(
PMethod_Check
(
meth
))
return
bindPMethod
((
PMethod
*
)
meth
,
inst
);
UNLESS
(
ExtensionInstance_Check
(
inst
))
return
PyErr_Format
(
PyExc_TypeError
,
"Attempt to use %s as method for %s, which is "
"not an extension class instance."
,
"OO"
,
meth
,
inst
);
if
(
meth
=
newPMethod
(
ExtensionClassOf
(
inst
),
meth
))
UNLESS_ASSIGN
(((
PMethod
*
)
meth
)
->
self
,
inst
)
return
NULL
;
Py_INCREF
(
inst
);
return
meth
;
}
static
void
PMethod_dealloc
(
PMethod
*
self
)
{
Py_DECREF
(
self
->
type
);
#ifdef TRACE_DEALLOC
fprintf
(
stderr
,
"Deallocating PM ... "
);
#endif
Py_XDECREF
(
self
->
type
);
Py_XDECREF
(
self
->
self
);
PyMem_DEL
(
self
);
#ifdef TRACE_DEALLOC
fprintf
(
stderr
,
" Done Deallocating PM
\n
"
);
#endif
}
static
PyObject
*
...
...
@@ -470,9 +526,9 @@ call_PMethod(PMethod *self, PyObject *inst, PyObject *args, PyObject *kw)
{
PyObject
*
a
;
UNLESS
(
a
=
Py_BuildValue
(
"(O)"
,
inst
))
return
NULL
;
UNLESS_ASSIGN
(
a
,
PySequence_Concat
(
a
,
args
))
return
NULL
;
UNLESS_ASSIGN
(
a
,
PyEval_CallObjectWithKeywords
(
self
->
meth
,
a
,
kw
))
return
NULL
;
a
=
Py_BuildValue
(
"(O)"
,
inst
)
;
if
(
a
)
ASSIGN
(
a
,
PySequence_Concat
(
a
,
args
))
;
if
(
a
)
ASSIGN
(
a
,
PyEval_CallObjectWithKeywords
(
self
->
meth
,
a
,
kw
))
;
return
a
;
}
...
...
@@ -480,40 +536,49 @@ static PyObject *
PMethod_call
(
PMethod
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
int
size
;
char
*
buf
;
PyObject
*
s
;
if
(
self
->
self
)
return
call_PMethod
(
self
,
self
->
self
,
args
,
kw
);
if
((
size
=
PyTuple_Size
(
args
))
>
0
)
{
PyObject
*
first
=
0
;
PyObject
*
first
=
0
,
*
ftype
=
0
;
UNLESS
(
first
=
PyTuple_GET_ITEM
(
args
,
0
))
return
NULL
;
if
(
first
->
ob_type
==
self
->
type
||
(
PyExtensionInstance_Check
(
first
)
&&
CMethod_issubclass
(
PyExtensionClassOf
(
first
),
AsPyExtensionClass
(
self
->
type
))
if
(
!
self
->
type
||
((
ftype
=
PyObject_GetAttr
(
first
,
py__class__
))
&&
(
ftype
==
(
PyObject
*
)
self
->
type
||
(
ExtensionClass_Check
(
ftype
)
&&
CMethod_issubclass
(
AsExtensionClass
(
ftype
),
AsExtensionClass
(
self
->
type
))
)
)
)
);
{
PyObject
*
rest
=
0
;
UNLESS
(
rest
=
PySequence_GetSlice
(
args
,
1
,
size
))
return
NULL
;
return
call_PMethod
(
self
,
first
,
rest
,
kw
);
}
)
{
if
(
NeedsToBeBound
(
self
->
meth
))
{
PyObject
*
r
,
*
rest
;
UNLESS
(
r
=
CallMethodO
(
self
->
meth
,
py__of__
,
Build
(
"(O)"
,
first
),
NULL
))
return
NULL
;
UNLESS
(
rest
=
PySequence_GetSlice
(
args
,
1
,
size
))
{
Py_DECREF
(
r
);
return
NULL
;
}
ASSIGN
(
r
,
PyEval_CallObjectWithKeywords
(
r
,
rest
,
kw
));
Py_DECREF
(
rest
);
return
r
;
}
Py_DECREF
(
ftype
);
return
PyEval_CallObjectWithKeywords
(
self
->
meth
,
args
,
kw
);
}
Py_XDECREF
(
ftype
);
}
/* Call of unbound method without instance argument */
size
=
strlen
(
self
->
type
->
tp_name
);
UNLESS
(
s
=
PyString_FromStringAndSize
(
NULL
,
size
+
48
))
return
NULL
;
buf
=
PyString_AsString
(
s
);
sprintf
(
buf
,
"unbound Python method must be called with %s 1st argument"
,
self
->
type
->
tp_name
);
PyErr_SetObject
(
PyExc_TypeError
,
s
);
Py_DECREF
(
s
);
return
NULL
;
return
PyErr_Format
(
PyExc_TypeError
,
"unbound Python method must be called with %s"
" 1st argument"
,
"s"
,
self
->
type
->
tp_name
);
}
static
PyObject
*
...
...
@@ -544,37 +609,39 @@ PMethod_getattr(PMethod *self, char *name)
Py_INCREF
(
r
);
return
r
;
}
PyErr_SetString
(
PyExc_AttributeError
,
name
);
return
NULL
;
}
static
PyTypeObject
PMethodType
=
{
PyObject_HEAD_INIT
(
&
PyType_Type
)
0
,
/*ob_size*/
"Python Method"
,
/*tp_name*/
sizeof
(
PMethod
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
PMethod_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
PMethod_getattr
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
PMethod_call
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
/* Space for future expansion */
0L
,
0L
,
0L
,
0L
,
"Storage manager for unbound C function PyObject data"
/* Documentation string */
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"Python Method"
,
/*tp_name*/
sizeof
(
PMethod
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
PMethod_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
PMethod_getattr
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
PMethod_call
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
/* Space for future expansion */
0L
,
0L
,
0L
,
0L
,
"Storage manager for unbound C function PyObject data"
/* Documentation string */
};
/* Special Methods */
static
PyObject
*
CCL_getattr
(
PyExtensionClass
*
,
PyObject
*
,
int
);
#define HAS(M) (M && ((void*)M != (void*)MetaTypeUndefinedMethod))
/* Special Methods */
#define UNARY_OP(OP) \
static PyObject * \
...
...
@@ -604,7 +671,7 @@ static PyObject *
compare_by_name
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
other
;
long
r
;
UNLESS
(
PyArg_Parse
(
args
,
"O"
,
&
other
))
return
NULL
;
return
PyInt_FromLong
(
self
->
ob_type
->
tp_compare
(
self
,
other
));
}
...
...
@@ -628,8 +695,6 @@ setattr_by_name(PyObject *self, PyObject *args)
return
Py_None
;
}
#if PYTHON_API_VERSION >= 1005
static
PyObject
*
getattro_by_name
(
PyObject
*
self
,
PyObject
*
args
)
{
...
...
@@ -648,8 +713,6 @@ setattro_by_name(PyObject *self, PyObject *args)
Py_INCREF
(
Py_None
);
return
Py_None
;
}
#endif
static
PyObject
*
length_by_name
(
PyObject
*
self
,
PyObject
*
args
)
...
...
@@ -688,20 +751,24 @@ getitem_by_name(PyObject *self, PyObject *args)
static
PyCFunction
item_by_name
=
(
PyCFunction
)
getitem_by_name
;
static
PyCFunction
subscript_by_name
=
(
PyCFunction
)
getitem_by_name
;
static
int
static
PyObject
*
setitem_by_name
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
key
,
*
v
;
long
r
;
UNLESS
(
PyArg_Parse
(
args
,
"OO"
,
&
key
,
&
v
))
return
NULL
;
if
(
self
->
ob_type
->
tp_as_mapping
)
r
eturn
self
->
ob_type
->
tp_as_mapping
->
mp_ass_subscript
(
self
,
key
,
v
);
r
=
self
->
ob_type
->
tp_as_mapping
->
mp_ass_subscript
(
self
,
key
,
v
);
else
{
int
index
;
UNLESS
(
-
1
!=
(
index
=
PyInt_AsLong
(
key
)))
return
-
1
;
r
eturn
self
->
ob_type
->
tp_as_sequence
->
sq_ass_item
(
self
,
index
,
v
);
UNLESS
(
-
1
!=
(
index
=
PyInt_AsLong
(
key
)))
return
NULL
;
r
=
self
->
ob_type
->
tp_as_sequence
->
sq_ass_item
(
self
,
index
,
v
);
}
if
(
r
<
0
)
return
NULL
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyCFunction
ass_item_by_name
=
(
PyCFunction
)
setitem_by_name
;
...
...
@@ -716,14 +783,18 @@ slice_by_name(PyObject *self, PyObject *args)
return
self
->
ob_type
->
tp_as_sequence
->
sq_slice
(
self
,
i1
,
i2
);
}
static
int
static
PyObject
*
ass_slice_by_name
(
PyObject
*
self
,
PyObject
*
args
)
{
int
i1
,
i2
;
PyObject
*
v
;
long
r
;
UNLESS
(
PyArg_Parse
(
args
,
"iiO"
,
&
i1
,
&
i2
,
&
v
))
return
-
1
;
return
self
->
ob_type
->
tp_as_sequence
->
sq_ass_slice
(
self
,
i1
,
i2
,
v
);
UNLESS
(
PyArg_Parse
(
args
,
"iiO"
,
&
i1
,
&
i2
,
&
v
))
return
NULL
;
r
=
self
->
ob_type
->
tp_as_sequence
->
sq_ass_slice
(
self
,
i1
,
i2
,
v
);
if
(
r
<
0
)
return
NULL
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyObject
*
...
...
@@ -817,10 +888,9 @@ UNOP(hex)
#define FILLENTRY(T,MN,N,F,D) if(T ## _ ## MN) { \
UNLESS(-1 != PyMapping_SetItemString(dict,"__" # N "__", \
(PyObject*)newCMethod((PyTypeObject *)type,"__" # N "__", \
(PyCFunction)MN ## _by_name, F, # D))) \
goto err; \
}
newCMethod(type, NULL, "__" # N "__", \
(PyCFunction)MN ## _by_name, F, # D))) \
goto err; }
static
PyObject
*
getBaseDictionary
(
PyExtensionClass
*
type
)
...
...
@@ -830,7 +900,8 @@ getBaseDictionary(PyExtensionClass *type)
PyMappingMethods
*
mm
;
PyObject
*
dict
;
UNLESS
(
dict
=
PyDict_New
())
return
NULL
;
UNLESS
(
dict
=
type
->
class_dictionary
)
UNLESS
(
dict
=
PyDict_New
())
return
NULL
;
FILLENTRY
(
type
->
tp
,
repr
,
repr
,
0
,
"convert to an expression string"
);
FILLENTRY
(
type
->
tp
,
hash
,
hash
,
0
,
"compute a hash value"
);
...
...
@@ -838,11 +909,8 @@ getBaseDictionary(PyExtensionClass *type)
FILLENTRY
(
type
->
tp
,
compare
,
comp
,
0
,
"compare with another object"
);
FILLENTRY
(
type
->
tp
,
getattr
,
getattr
,
0
,
"Get an attribute"
);
FILLENTRY
(
type
->
tp
,
setattr
,
setattr
,
0
,
"Set an attribute"
);
#if PYTHON_API_VERSION >= 1005
FILLENTRY
(
type
->
tp
,
getattro
,
getattr
,
0
,
"Get an attribute"
);
FILLENTRY
(
type
->
tp
,
setattro
,
setattr
,
0
,
"Set an attribute"
);
#endif
if
(
sm
=
type
->
tp_as_sequence
)
{
...
...
@@ -900,24 +968,109 @@ err:
return
NULL
;
}
#undef HAS
#undef UNARY_OP
#undef BINOP
#undef UNOP
#undef FILLENTRY
PyObject
*
EC_reduce
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
state
=
0
;
if
(
args
=
PyObject_GetAttr
(
self
,
py__getinitargs__
))
{
UNLESS_ASSIGN
(
args
,
PyEval_CallObject
(
args
,
NULL
))
return
NULL
;
UNLESS_ASSIGN
(
args
,
PySequence_Tuple
(
args
))
return
NULL
;
}
else
{
PyErr_Clear
();
args
=
PyTuple_New
(
0
);
}
if
(
state
=
PyObject_GetAttr
(
self
,
py__getstate__
))
{
UNLESS_ASSIGN
(
state
,
PyEval_CallObject
(
state
,
NULL
))
goto
err
;
ASSIGN
(
args
,
Py_BuildValue
(
"OOO"
,
self
->
ob_type
,
args
,
state
));
Py_DECREF
(
state
);
}
else
{
PyErr_Clear
();
if
(
state
=
PyObject_GetAttr
(
self
,
py__dict__
))
{
ASSIGN
(
args
,
Py_BuildValue
(
"OOO"
,
self
->
ob_type
,
args
,
state
));
Py_DECREF
(
state
);
}
else
{
PyErr_Clear
();
ASSIGN
(
args
,
Py_BuildValue
(
"OO"
,
self
->
ob_type
,
args
));
}
}
return
args
;
err:
Py_DECREF
(
args
);
return
NULL
;
}
static
PyObject
*
inheritedAttribute
(
PyExtensionClass
*
self
,
PyObject
*
name
)
{
UNLESS
(
name
)
return
PyErr_Format
(
PyExc_TypeError
,
"expected one argument, and none given"
,
NULL
);
return
CCL_getattr
(
self
,
name
,
1
);
}
static
PyObject
*
inheritedClassAttribute
(
PyExtensionClass
*
self
,
PyObject
*
name
)
{
UNLESS
(
name
)
return
PyErr_Format
(
PyExc_TypeError
,
"expected one argument, and none given"
,
NULL
);
UNLESS
(
name
=
PySequence_Concat
(
pyclass_
,
name
))
return
NULL
;
UNLESS_ASSIGN
(
name
,
CCL_getattr
(
self
,
name
,
1
))
return
NULL
;
if
(
UnboundPMethod_Check
(
name
))
ASSIGN
(
name
,
bindPMethod
((
PMethod
*
)
name
,(
PyObject
*
)
self
));
return
name
;
}
struct
PyMethodDef
ECI_methods
[]
=
{
{
"__reduce__"
,(
PyCFunction
)
EC_reduce
,
0
,
"__reduce__() -- Reduce an instance into it's class and creation data"
},
{
NULL
,
NULL
}
/* sentinel */
};
static
PyObject
*
initializeBaseExtensionClass
(
PyExtensionClass
*
self
)
{
PyMethodChain
*
chain
;
PyMethodChain
*
chain
,
top
=
{
ECI_methods
,
NULL
}
;
PyObject
*
dict
;
self
->
ob_type
=
(
PyTypeObject
*
)
&
CCLt
ype
;
self
->
ob_type
=
(
PyTypeObject
*
)
&
ECT
ype
;
Py_INCREF
(
self
->
ob_type
);
UNLESS
(
dict
=
self
->
class_dictionary
=
getBaseDictionary
(
self
))
return
NULL
;
if
(
self
->
tp_name
)
{
PyObject
*
name
;
UNLESS
(
name
=
PyString_FromString
(
self
->
tp_name
))
goto
err
;
if
(
0
>
PyMapping_SetItemString
(
dict
,
"__doc__"
,
name
))
goto
err
;
Py_DECREF
(
name
);
}
else
if
(
0
>
PyMapping_SetItemString
(
dict
,
"__doc__"
,
Py_None
))
goto
err
;
top
.
link
=&
(
self
->
methods
);
chain
=&
(
self
->
methods
)
;
chain
=&
top
;
while
(
chain
!=
NULL
)
{
PyMethodDef
*
ml
=
chain
->
methods
;
...
...
@@ -927,8 +1080,7 @@ initializeBaseExtensionClass(PyExtensionClass *self)
{
UNLESS
(
-
1
!=
PyMapping_SetItemString
(
dict
,
ml
->
ml_name
,
(
PyObject
*
)
newCMethod
((
PyTypeObject
*
)
self
,
newCMethod
(
self
,
NULL
,
ml
->
ml_name
,
ml
->
ml_meth
,
ml
->
ml_flags
,
...
...
@@ -953,18 +1105,34 @@ initializeBaseExtensionClass(PyExtensionClass *self)
chain
=
chain
->
link
;
}
return
(
PyObject
*
)
self
;
err:
Py_DECREF
(
dict
);
return
NULL
;
}
static
void
CCL_dealloc
(
PyExtensionClass
*
self
)
{
#ifdef TRACE_DEALLOC
fprintf
(
stderr
,
"Deallocating %s
\n
"
,
self
->
tp_name
);
#endif
Py_XDECREF
(
self
->
class_dictionary
);
Py_XDECREF
(
self
->
bases
);
if
(
self
->
bases
)
{
/* If we are a subclass, then we strduped our name */
free
(
self
->
tp_name
);
/* And we allocated our own protocol structures */
if
(
self
->
tp_as_number
)
free
(
self
->
tp_as_number
);
if
(
self
->
tp_as_sequence
)
free
(
self
->
tp_as_sequence
);
if
(
self
->
tp_as_mapping
)
free
(
self
->
tp_as_mapping
);
Py_DECREF
(
self
->
bases
);
}
Py_XDECREF
(
self
->
ob_type
);
PyMem_DEL
(
self
);
}
static
PyObject
*
CCL_getattr
();
static
PyObject
*
ExtensionClass_FindInstanceAttribute
(
PyObject
*
inst
,
PyObject
*
oname
,
...
...
@@ -985,12 +1153,13 @@ ExtensionClass_FindInstanceAttribute(PyObject *inst, PyObject *oname,
if
(
*
name
==
'_'
&&
name
[
1
]
==
'_'
)
{
if
(
strcmp
(
name
+
2
,
"class__"
)
==
0
)
char
*
n
=
name
+
2
;
if
(
*
n
==
'c'
&&
strcmp
(
n
,
"class__"
)
==
0
)
{
Py_INCREF
(
self
);
return
(
PyObject
*
)
self
;
}
if
(
self
->
bases
&&
strcmp
(
name
+
2
,
"dict__"
)
==
0
)
if
(
self
->
bases
&&
*
n
==
'd'
&&
strcmp
(
n
,
"dict__"
)
==
0
)
{
r
=
INSTANCE_DICT
(
inst
);
Py_INCREF
(
r
);
...
...
@@ -1001,39 +1170,22 @@ ExtensionClass_FindInstanceAttribute(PyObject *inst, PyObject *oname,
if
(
self
->
bases
)
{
r
=
INSTANCE_DICT
(
inst
);
r
=
PyObject_GetItem
(
r
,
oname
);
if
((
r
=
PyObject_GetItem
(
r
,
oname
))
&&
NeedsToBeBound
(
r
))
{
ASSIGN
(
r
,
CallMethodO
(
r
,
py__of__
,
Build
(
"(O)"
,
inst
),
NULL
));
UNLESS
(
r
)
return
NULL
;
}
}
UNLESS
(
r
)
{
PyErr_Clear
();
UNLESS
(
r
=
CCL_getattr
(
self
,
oname
,
name
))
return
NULL
;
UNLESS
(
r
=
CCL_getattr
(
self
,
oname
,
0
))
return
NULL
;
/* We got something from our class, maybe its an unbound method. */
if
(
UnboundCMethod_Check
(
r
))
{
UNLESS_ASSIGN
(
r
,(
PyObject
*
)
bindCMethod
((
CMethod
*
)
r
,
inst
))
return
NULL
;
}
ASSIGN
(
r
,(
PyObject
*
)
bindCMethod
((
CMethod
*
)
r
,
inst
));
else
if
(
UnboundPMethod_Check
(
r
))
{
PyObject
*
m
;
m
=
((
PMethod
*
)
r
)
->
meth
;
if
(
PyExtensionInstance_Check
(
m
)
&&
(
PyExtensionClassOf
(
m
)
->
class_flags
&
EXTENSIONCLASS_BINDABLE_FLAG
)
)
{
UNLESS_ASSIGN
(
r
,
PyObject_CallMethod
(
m
,
"__bind_to_object__"
,
"O"
,
inst
))
return
NULL
;
}
else
{
UNLESS_ASSIGN
(
r
,(
PyObject
*
)
bindPMethod
((
PMethod
*
)
r
,
inst
))
return
NULL
;
}
}
ASSIGN
(
r
,
bindPMethod
((
PMethod
*
)
r
,
inst
));
}
return
r
;
...
...
@@ -1061,69 +1213,33 @@ static int
subclass_simple_setattr
(
PyObject
*
self
,
char
*
name
,
PyObject
*
v
);
static
PyObject
*
CCL_getattr
(
PyExtensionClass
*
self
,
PyObject
*
oname
,
char
*
name
)
CCL_getattr
(
PyExtensionClass
*
self
,
PyObject
*
oname
,
int
look_super
)
{
PyObject
*
r
;
int
local
=
1
;
char
*
n
;
if
(
!
name
)
return
NULL
;
PyObject
*
r
=
0
;
if
(
*
name
==
'.'
)
{
n
=
name
+
1
;
if
(
*
n
==
0
)
return
(
PyObject
*
)
EC_findiattrs
;
if
(
*
n
==
'o'
&&
n
[
1
]
==
0
)
return
(
PyObject
*
)
EC_findiattro
;
if
(
*
n
==
's'
&&
n
[
1
]
==
0
)
return
(
PyObject
*
)
subclass_simple_setattr
;
}
if
(
*
name
==
'_'
&&
name
[
1
]
==
'_'
)
{
n
=
name
+
2
;
if
(
strcmp
(
n
,
"doc__"
)
==
0
&&
self
->
tp_doc
)
return
PyString_FromString
(
self
->
tp_doc
);
if
(
strcmp
(
n
,
"name__"
)
==
0
)
return
PyString_FromString
(
self
->
tp_name
);
if
(
strcmp
(
n
,
"dict__"
)
==
0
)
{
Py_INCREF
(
self
->
class_dictionary
);
return
self
->
class_dictionary
;
}
if
(
strcmp
(
n
,
"bases__"
)
==
0
)
{
if
(
self
->
bases
)
{
Py_INCREF
(
self
->
bases
);
return
self
->
bases
;
}
else
return
PyTuple_New
(
0
);
}
}
r
=
PyObject_GetItem
(
self
->
class_dictionary
,
oname
);
if
(
!
look_super
)
r
=
PyObject_GetItem
(
self
->
class_dictionary
,
oname
);
UNLESS
(
r
)
{
local
=
0
;
if
(
self
->
bases
)
{
int
n
,
i
;
PyObject
*
c
;
n
=
PyTuple_Size
(
self
->
bases
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
PyErr_Clear
();
c
=
PyTuple_GET_ITEM
(
self
->
bases
,
i
);
if
(
r
=
PyObject_GetAttr
(
c
,
oname
))
break
;
if
(
ExtensionClass_Check
(
c
))
r
=
CCL_getattr
(
AsExtensionClass
(
c
),
oname
,
0
);
else
r
=
PyObject_GetAttr
(
c
,
oname
);
if
(
r
)
break
;
}
}
UNLESS
(
r
)
{
PyObject
*
t
,
*
v
,
*
tb
;
char
*
s
;
PyErr_Fetch
(
&
t
,
&
v
,
&
tb
);
if
(
t
==
PyExc_KeyError
&&
PyObject_Compare
(
v
,
oname
)
==
0
)
...
...
@@ -1137,64 +1253,99 @@ CCL_getattr(PyExtensionClass *self, PyObject *oname, char *name)
}
}
if
(
PyFunction_Check
(
r
)
||
(
PyExtensionInstance_Check
(
r
)
&&
(
PyExtensionClassOf
(
r
)
->
class_flags
&
EXTENSIONCLASS_BINDABLE_FLAG
)
)
)
if
(
PyFunction_Check
(
r
)
||
NeedsToBeBound
(
r
))
{
UNLESS_ASSIGN
(
r
,(
PyObject
*
)
newPMethod
((
PyTypeObject
*
)
self
,
r
))
return
NULL
;
UNLESS_ASSIGN
(
r
,
newPMethod
(
self
,
r
))
return
NULL
;
}
else
if
(
PyMethod_Check
(
r
)
&&
!
PyMethod_Self
(
r
))
{
UNLESS_ASSIGN
(
r
,(
PyObject
*
)
newPMethod
((
PyTypeObject
*
)
self
,
PyMethod_Function
(
r
)))
UNLESS_ASSIGN
(
r
,
newPMethod
(
self
,
PyMethod_Function
(
r
)))
return
NULL
;
}
else
local
=
0
;
if
(
local
)
/* We have a PMethod that we built from our dict, cache it */
{
UNLESS
(
-
1
!=
PyObject_SetItem
(
self
->
class_dictionary
,
oname
,
r
))
PyErr_Clear
();
/* Oh well */
}
return
r
;
}
PyObject
*
CCL_getattrs
(
PyExtensionClass
*
self
,
char
*
name
)
{
PyObject
*
s
,
*
r
;
UNLESS
(
s
=
PyString_FromString
(
name
))
return
NULL
;
r
=
CCL_getattr
(
self
,
s
,
name
);
Py_DECREF
(
s
);
return
r
;
}
static
int
CCL_setattrs
(
self
,
name
,
v
)
PyExtensionClass
*
self
;
char
*
name
;
PyObject
*
v
;
static
PyObject
*
CCL_reduce
(
PyExtensionClass
*
self
,
PyObject
*
args
)
{
return
Py
Mapping_SetItemString
(
self
->
class_dictionary
,
name
,
v
);
return
Py
String_FromString
(
self
->
tp_name
);
}
PyObject
*
CCL_getattro
(
PyExtensionClass
*
self
,
PyObject
*
name
)
{
return
CCL_getattr
(
self
,
name
,
PyString_AsString
(
name
));
char
*
n
,
*
nm
=
0
;
PyObject
*
r
;
if
(
PyString_Check
(
name
)
&&
(
n
=
nm
=
PyString_AS_STRING
((
PyStringObject
*
)
name
)))
{
if
(
*
n
==
'_'
&&
*++
n
==
'_'
)
{
switch
(
*++
n
)
{
case
's'
:
if
(
strcmp
(
n
,
"safe_for_unpickling__"
)
==
0
)
return
PyInt_FromLong
(
1
);
break
;
case
'n'
:
if
(
strcmp
(
n
,
"name__"
)
==
0
)
return
PyString_FromString
(
self
->
tp_name
);
break
;
case
'r'
:
if
(
strcmp
(
n
,
"reduce__"
)
==
0
)
return
newCMethod
(
self
,(
PyObject
*
)
self
,
"__reduce__"
,(
PyCFunction
)
CCL_reduce
,
0
,
"__reduce__() -- Reduce the class to a class name"
);
break
;
case
'd'
:
if
(
strcmp
(
n
,
"dict__"
)
==
0
)
{
Py_INCREF
(
self
->
class_dictionary
);
return
self
->
class_dictionary
;
}
break
;
case
'b'
:
if
(
strcmp
(
n
,
"bases__"
)
==
0
)
{
if
(
self
->
bases
)
{
Py_INCREF
(
self
->
bases
);
return
self
->
bases
;
}
else
return
PyTuple_New
(
0
);
}
break
;
}
}
}
if
(
strcmp
(
nm
,
"inheritedAttribute"
)
==
0
)
{
return
newCMethod
(
self
,(
PyObject
*
)
self
,
"inheritedAttribute"
,(
PyCFunction
)
inheritedAttribute
,
0
,
"look up an attribute in a class's super classes"
);
}
if
(
nm
&&
*
nm
++==
'c'
&&
*
nm
++==
'l'
&&
*
nm
++==
'a'
&&
*
nm
++==
's'
&&
*
nm
++==
's'
&&
*
nm
==
'_'
)
{
UNLESS
(
r
=
CCL_getattr
(
self
,
name
,
0
))
return
NULL
;
if
(
UnboundPMethod_Check
(
r
))
ASSIGN
(
r
,
bindPMethod
((
PMethod
*
)
r
,(
PyObject
*
)
self
));
return
r
;
}
if
(
r
=
CCL_getattr
(
self
,
name
,
0
))
return
r
;
return
NULL
;
}
static
int
CCL_setattro
(
PyExtensionClass
*
self
,
PyObject
*
name
,
PyObject
*
v
)
{
if
(
UnboundCMethod_Check
(
v
))
if
(
v
&&
UnboundCMethod_Check
(
v
))
{
char
*
n
;
PyNumberMethods
*
nm
;
...
...
@@ -1319,19 +1470,14 @@ static PyObject *
CCL_call
(
PyExtensionClass
*
self
,
PyObject
*
arg
,
PyObject
*
kw
)
{
PyObject
*
inst
=
0
,
*
init
=
0
,
*
args
=
0
;
int
check
;
struct
Dataless
{
PyObject_HEAD
};
typedef
struct
{
PyObject_VAR_HEAD
}
PyVarObject__
;
if
(
PyArg_ParseTuple
(
arg
,
"Oi"
,
&
inst
,
&
check
)
)
if
(
!
self
->
tp_dealloc
)
{
if
(
check
==
42
&&
inst
->
ob_type
==&
PyType_Type
)
{
initializeBaseExtensionClass
((
PyExtensionClass
*
)
inst
);
return
(
PyObject
*
)
inst
;
}
PyErr_SetString
(
PyExc_TypeError
,
"Attempt to create instance of an abstract type"
);
return
NULL
;
}
else
PyErr_Clear
();
if
(
self
->
tp_itemsize
)
{
...
...
@@ -1339,17 +1485,17 @@ CCL_call(PyExtensionClass *self, PyObject *arg, PyObject *kw)
PyObject
*
var_size
;
int
size
;
if
(
var_size
=
CCL_getattr
o
(
self
,
py__var_size__
))
if
(
var_size
=
CCL_getattr
(
self
,
py__var_size__
,
0
))
{
UNLESS_ASSIGN
(
var_size
,
PyObject_CallObject
(
var_size
,
arg
s
))
UNLESS_ASSIGN
(
var_size
,
PyObject_CallObject
(
var_size
,
arg
))
return
NULL
;
}
else
{
UNLESS
(
-
1
!=
(
size
=
PyTuple_Size
(
arg
s
)))
return
NULL
;
UNLESS
(
-
1
!=
(
size
=
PyTuple_Size
(
arg
)))
return
NULL
;
if
(
size
>
0
)
{
var_size
=
PyTuple_GET_ITEM
(
arg
s
,
0
);
var_size
=
PyTuple_GET_ITEM
(
arg
,
0
);
if
(
PyInt_Check
(
var_size
))
size
=
PyInt_AsLong
(
var_size
);
else
...
...
@@ -1385,9 +1531,7 @@ CCL_call(PyExtensionClass *self, PyObject *arg, PyObject *kw)
UNLESS
(
INSTANCE_DICT
(
inst
)
=
PyDict_New
())
goto
err
;
}
if
(
init
=
CCL_getattro
(
self
,
py__init__
))
if
(
init
=
CCL_getattr
(
self
,
py__init__
,
0
))
{
UNLESS
(
args
=
Py_BuildValue
(
"(O)"
,
inst
))
goto
err
;
if
(
arg
)
UNLESS_ASSIGN
(
args
,
PySequence_Concat
(
args
,
arg
))
goto
err
;
...
...
@@ -1397,7 +1541,6 @@ CCL_call(PyExtensionClass *self, PyObject *arg, PyObject *kw)
}
else
PyErr_Clear
();
return
inst
;
err:
Py_DECREF
(
inst
);
...
...
@@ -1409,29 +1552,24 @@ err:
static
PyObject
*
CCL_repr
(
PyExtensionClass
*
self
)
{
PyObject
*
s
;
int
l
;
char
*
buf
,
p
[
64
];
char
p
[
128
];
sprintf
(
p
,
"%p"
,
self
);
l
=
strlen
(
self
->
ob_type
->
tp_name
)
+
strlen
(
p
);
UNLESS
(
s
=
PyString_FromStringAndSize
(
NULL
,
l
+
22
))
return
NULL
;
buf
=
PyString_AsString
(
s
);
sprintf
(
buf
,
"<extension class %s at %p>"
,
self
->
tp_name
,
self
);
return
s
;
return
PyString_Build
(
"<extension class %s at %s>"
,
"ss"
,
self
->
tp_name
,
p
);
}
static
PyTypeObject
CCLtype_class
=
{
PyObject_HEAD_INIT
(
&
PyType_Type
)
static
PyTypeObject
ECTypeType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"
C Class Class"
,
/*tp_name*/
"
ExtensionClass Class"
,
/*tp_name*/
sizeof
(
PyExtensionClass
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
CCL_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
CCL_getattrs
,
/*tp_getattr*/
(
setattrfunc
)
CCL_setattrs
,
/*tp_setattr*/
(
getattrfunc
)
0
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
CCL_repr
,
/*tp_repr*/
0
,
/*tp_as_number*/
...
...
@@ -1440,14 +1578,10 @@ static PyTypeObject CCLtype_class = {
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
CCL_call
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
#if PYTHON_API_VERSION >= 1005
(
getattrofunc
)
CCL_getattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
CCL_setattro
,
/*tp_setattr with object key*/
#else
/* Space for future expansion */
0L
,
0L
,
#endif
0L
,
0L
,
"Class of C classes"
/* Documentation string */
};
...
...
@@ -1468,7 +1602,7 @@ subclass_getspecial(PyObject *inst, PyObject *oname)
UNLESS
(
r
)
{
PyErr_Clear
();
r
=
CCL_getattr
(
self
,
oname
,
""
);
r
=
CCL_getattr
(
self
,
oname
,
0
);
}
return
r
;
...
...
@@ -1477,36 +1611,34 @@ subclass_getspecial(PyObject *inst, PyObject *oname)
static
PyObject
*
subclass_getattro
(
PyObject
*
self
,
PyObject
*
name
)
{
PyObject
*
r
=
0
;
PyObject
*
r
;
if
(
!
name
)
return
NULL
;
UNLESS
(
r
=
EC_findiattro
(
self
,
name
))
{
PyErr_Clear
();
UNLESS
(
r
=
EC_findiattro
(
self
,
py__getattr__
))
return
NULL
;
UNLESS_ASSIGN
(
r
,
PyObject_CallFunction
(
r
,
"O"
,
name
))
return
NULL
;
r
=
EC_findiattro
(
self
,
py__getattr__
)
;
if
(
r
)
ASSIGN
(
r
,
PyObject_CallFunction
(
r
,
"O"
,
name
))
;
}
return
r
;
}
static
PyObject
*
subclass_getattrs
(
PyObject
*
self
,
char
*
name
)
{
return
subclass_getattro
(
self
,
PyString_FromString
(
name
));
}
static
int
subclass_simple_setattro
(
PyObject
*
self
,
PyObject
*
name
,
PyObject
*
v
)
{
Py_INCREF
(
v
);
return
PyDict_SetItem
(
INSTANCE_DICT
(
self
),
name
,
v
);
if
(
v
)
return
PyDict_SetItem
(
INSTANCE_DICT
(
self
),
name
,
v
);
else
return
PyDict_DelItem
(
INSTANCE_DICT
(
self
),
name
);
}
static
int
subclass_simple_setattr
(
PyObject
*
self
,
char
*
name
,
PyObject
*
v
)
{
Py_INCREF
(
v
);
return
PyDict_SetItemString
(
INSTANCE_DICT
(
self
),
name
,
v
);
if
(
v
)
return
PyDict_SetItemString
(
INSTANCE_DICT
(
self
),
name
,
v
);
else
return
PyDict_DelItemString
(
INSTANCE_DICT
(
self
),
name
);
}
static
int
...
...
@@ -1516,16 +1648,26 @@ subclass_setattr(PyObject *self, PyObject *oname, char *name, PyObject *v)
if
(
!
name
)
return
-
1
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__setattr__
))
goto
default_setattr
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
setattr_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
if
(
!
v
&&
(
m
=
subclass_getspecial
(
self
,
py__delattr__
)))
{
UNLESS
(
-
1
!=
AsCMethod
(
m
)
->
type
->
tp_setattr
(
self
,
name
,
v
))
goto
dictionary_setattr
;
return
0
;
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
self
,
oname
))
return
-
1
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
oname
))
return
-
1
;
Py_DECREF
(
m
);
return
0
;
}
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__setattr__
))
goto
default_setattr
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
setattr_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
UNLESS
(
-
1
!=
AsCMethod
(
m
)
->
type
->
tp_setattr
(
self
,
name
,
v
))
goto
dictionary_setattr
;
return
0
;
}
#if PYTHON_API_VERSION >= 1005
else
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
setattro_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
...
...
@@ -1534,7 +1676,7 @@ subclass_setattr(PyObject *self, PyObject *oname, char *name, PyObject *v)
goto
dictionary_setattr
;
return
0
;
}
#endif
if
(
!
v
)
goto
default_setattr
;
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OOO"
,
self
,
oname
,
v
))
return
-
1
;
...
...
@@ -1574,18 +1716,6 @@ default_setattr:
return
subclass_simple_setattro
(
self
,
oname
,
v
);
}
static
int
subclass_setattrs
(
PyObject
*
self
,
char
*
name
,
PyObject
*
v
)
{
PyObject
*
s
;
int
r
;
UNLESS
(
s
=
PyString_FromString
(
name
))
return
-
1
;
r
=
subclass_setattr
(
self
,
s
,
name
,
v
);
Py_DECREF
(
s
);
return
r
;
}
static
int
subclass_setattro
(
PyObject
*
self
,
PyObject
*
name
,
PyObject
*
v
)
{
...
...
@@ -1641,67 +1771,59 @@ subclass_hash(PyObject *self)
return
r
;
}
static
PyObject
*
default_subclass_repr
(
PyObject
*
self
)
{
char
p
[
64
];
PyErr_Clear
();
sprintf
(
p
,
"%p"
,
self
);
return
PyString_Build
(
"<%s instance at %s>"
,
"ss"
,
self
->
ob_type
->
tp_name
,
p
);
}
static
PyObject
*
subclass_repr
(
PyObject
*
self
)
{
PyObject
*
m
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__repr__
))
{
int
l
;
char
*
buf
,
p
[
64
];
return
default_subclass_repr
(
self
);
PyErr_Clear
();
sprintf
(
p
,
"%p"
,
self
);
l
=
strlen
(
self
->
ob_type
->
tp_name
)
+
strlen
(
p
);
UNLESS
(
m
=
PyString_FromStringAndSize
(
NULL
,
l
+
15
))
return
NULL
;
buf
=
PyString_AsString
(
m
);
sprintf
(
buf
,
"<%s instance at %s>"
,
self
->
ob_type
->
tp_name
,
p
);
return
m
;
}
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
repr_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
UNLESS_ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_repr
(
self
))
return
NULL
;
}
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_repr
(
self
));
else
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
self
));
else
{
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
self
))
return
NULL
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
""
))
return
NULL
;
}
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
""
));
return
m
;
}
static
PyObject
*
subclass_call
(
PyObject
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
PyObject
*
m
,
*
a
=
0
;
PyObject
*
m
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__call__
))
return
NULL
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
call_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
UNLESS_ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_call
(
self
,
args
,
kw
))
return
NULL
;
}
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_call
(
self
,
args
,
kw
));
else
{
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS
(
a
=
Py_BuildValue
(
"(O)"
,
self
))
goto
err
;
UNLESS_ASSIGN
(
a
,
PySequence_Concat
(
a
,
args
))
goto
err
;
args
=
a
;
PyObject
*
a
;
a
=
Py_BuildValue
(
"(O)"
,
self
);
if
(
a
)
ASSIGN
(
a
,
PySequence_Concat
(
a
,
args
));
if
(
a
)
ASSIGN
(
m
,
PyEval_CallObjectWithKeywords
(
m
,
a
,
kw
));
else
ASSIGN
(
m
,
NULL
);
Py_XDECREF
(
a
);
}
UNLESS_ASSIGN
(
m
,
PyEval_CallObjectWithKeywords
(
m
,
args
,
kw
))
goto
err
;
else
ASSIGN
(
m
,
PyEval_CallObjectWithKeywords
(
m
,
args
,
kw
));
}
Py_XDECREF
(
a
);
return
m
;
err:
Py_XDECREF
(
m
);
Py_XDECREF
(
a
);
}
static
PyObject
*
...
...
@@ -1716,18 +1838,11 @@ subclass_str(PyObject *self)
}
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
str_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
UNLESS_ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_str
(
self
))
return
NULL
;
}
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_str
(
self
));
else
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
self
));
else
{
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
self
))
return
NULL
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
""
))
return
NULL
;
}
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
""
));
return
m
;
}
...
...
@@ -1739,19 +1854,11 @@ subclass_ ## M(PyObject *self, PyObject *v) \
UNLESS(m=subclass_getspecial(self,py__ ## N ## __)) return NULL; \
if(UnboundCMethod_Check(m) && AsCMethod(m)->meth==M ## _by_name \
&& SubclassInstance_Check(self,AsCMethod(m)->type)) \
{ \
UNLESS_ASSIGN(m,PyNumber_ ## A(self,v)) \
return NULL; \
} \
ASSIGN(m,PyNumber_ ## A(self,v)); \
else if(UnboundEMethod_Check(m)) \
ASSIGN(m,PyObject_CallFunction(m,"OO",self,v)); \
else \
{ \
if(UnboundEMethod_Check(m)) \
{ \
UNLESS_ASSIGN(m,PyObject_CallFunction(m,"OO",self,v)) \
return NULL; \
} \
else UNLESS_ASSIGN(m,PyObject_CallFunction(m,"O",v)) return NULL; \
} \
ASSIGN(m,PyObject_CallFunction(m,"O",v)); \
return m; \
}
...
...
@@ -1768,23 +1875,14 @@ subclass_power(PyObject *self, PyObject *v, PyObject *w)
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__pow__
))
return
NULL
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
power_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
UNLESS_ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_number
->
nb_power
(
self
,
v
,
w
))
return
NULL
;
}
else
{
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OOO"
,
self
,
v
,
w
))
return
NULL
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
v
,
w
))
return
NULL
;
}
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_number
->
nb_power
(
self
,
v
,
w
));
else
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OOO"
,
self
,
v
,
w
));
else
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
v
,
w
));
return
m
;
}
BINSUB
(
divmod
,
divmod
,
Divmod
)
BINSUB
(
lshift
,
lshift
,
Lshift
)
BINSUB
(
rshift
,
rshift
,
Rshift
)
...
...
@@ -1807,8 +1905,7 @@ subclass_coerce(PyObject **self, PyObject **v)
{
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
*
self
,
v
))
return
NULL
;
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
*
self
,
v
))
return
-
1
;
}
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
*
v
))
return
-
1
;
if
(
m
==
Py_None
)
r
=-
1
;
...
...
@@ -1832,19 +1929,11 @@ subclass_ ## M(PyObject *self) \
UNLESS(m=subclass_getspecial(self,py__ ## N ## __)) return NULL; \
if(UnboundCMethod_Check(m) && AsCMethod(m)->meth==M ## _by_name \
&& SubclassInstance_Check(self,AsCMethod(m)->type)) \
{ \
UNLESS_ASSIGN(m,AsCMethod(m)->type->tp_as_number->nb_ ## M(self)) \
return NULL; \
} \
ASSIGN(m,AsCMethod(m)->type->tp_as_number->nb_ ## M(self)); \
else if(UnboundEMethod_Check(m)) \
ASSIGN(m,PyObject_CallFunction(m,"O",self)); \
else \
{ \
if(UnboundEMethod_Check(m)) \
{ \
UNLESS_ASSIGN(m,PyObject_CallFunction(m,"O",self)) \
return NULL; \
} \
else UNLESS_ASSIGN(m,PyObject_CallFunction(m,"")) return NULL; \
} \
ASSIGN(m,PyObject_CallFunction(m,"")); \
return m; \
}
...
...
@@ -1931,11 +2020,12 @@ subclass_length(PyObject *self)
else
return
t
->
tp_as_mapping
->
mp_length
(
self
);
}
else
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
""
))
return
-
1
;
r
=
PyInt_AsLong
(
m
);
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
self
))
return
-
1
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
""
))
return
-
1
;
r
=
PyInt_AsLong
(
m
);
Py_DECREF
(
m
);
return
r
;
}
...
...
@@ -1957,20 +2047,46 @@ subclass_item(PyObject *self, int index)
return
t
->
tp_as_sequence
->
sq_item
(
self
,
index
);
}
}
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"i"
,
index
))
goto
err
;
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"Oi"
,
self
,
index
));
else
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"i"
,
index
));
return
m
;
}
static
PyObject
*
subclass_slice
(
PyObject
*
self
,
int
i1
,
int
i2
)
{
PyObject
*
m
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__getslice__
))
return
NULL
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
slice_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_slice
(
self
,
i1
,
i2
));
else
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"Oii"
,
self
,
i1
,
i2
));
else
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"ii"
,
i1
,
i2
));
return
m
;
err:
Py_DECREF
(
m
);
return
NULL
;
}
static
long
subclass_ass_item
(
PyObject
*
self
,
int
index
,
PyObject
*
v
)
{
long
r
;
PyObject
*
m
;
PyExtensionClass
*
t
;
if
(
!
v
&&
(
m
=
subclass_getspecial
(
self
,
py__delitem__
)))
{
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"Oi"
,
self
,
index
))
return
-
1
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"i"
,
index
))
return
-
1
;
Py_DECREF
(
m
);
return
0
;
}
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__setitem__
))
return
-
1
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
setitem_by_name
...
...
@@ -1983,32 +2099,18 @@ subclass_ass_item(PyObject *self, int index, PyObject *v)
return
t
->
tp_as_sequence
->
sq_ass_item
(
self
,
index
,
v
);
}
}
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"iO"
,
index
,
v
))
return
-
1
;
r
=
PyInt_AsLong
(
m
);
Py_DECREF
(
m
);
return
r
;
err:
Py_DECREF
(
m
);
return
NULL
;
}
static
PyObject
*
subclass_slice
(
PyObject
*
self
,
int
i1
,
int
i2
)
{
PyObject
*
m
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__getslice__
))
return
NULL
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
slice_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
if
(
!
v
)
{
UNLESS_ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_slice
(
self
,
i1
,
i2
))
return
NULL
;
PyErr_SetObject
(
PyExc_AttributeError
,
py__delitem__
);
return
-
1
;
}
else
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"
ii"
,
i1
,
i2
))
return
NULL
;
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"
OiO"
,
self
,
index
,
v
))
return
-
1
;
}
return
m
;
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"iO"
,
index
,
v
))
return
-
1
;
Py_DECREF
(
m
);
return
0
;
}
static
int
...
...
@@ -2017,18 +2119,41 @@ subclass_ass_slice(PyObject *self, int i1, int i2, PyObject *v)
PyObject
*
m
;
long
r
;
if
(
!
v
&&
(
m
=
subclass_getspecial
(
self
,
py__delslice__
)))
{
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"Oii"
,
self
,
i1
,
i2
))
return
-
1
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"ii"
,
i1
,
i2
))
return
-
1
;
Py_DECREF
(
m
);
return
0
;
}
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__setslice__
))
return
-
1
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
ass_slice_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
r
=
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_ass_slice
(
self
,
i1
,
i2
,
v
);
else
{
r
=
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_ass_slice
(
self
,
i1
,
i2
,
v
);
Py_DECREF
(
m
);
return
r
;
}
if
(
!
v
)
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"iiO"
,
i1
,
i2
,
v
))
return
-
1
;
r
=
PyInt_AsLong
(
m
);
PyErr_SetObject
(
PyExc_AttributeError
,
py__delslice__
);
return
-
1
;
}
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OiiO"
,
self
,
i1
,
i2
,
v
))
return
-
1
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"iiO"
,
i1
,
i2
,
v
))
return
-
1
;
Py_DECREF
(
m
);
return
r
;
return
0
;
}
static
PyObject
*
...
...
@@ -2071,16 +2196,14 @@ subclass_concat(PyObject *self, PyObject *v)
"No __add__ or __concat__ methods, or maybe I'm just being stupid."
);
return
NULL
;
}
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
concat_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
UNLESS_ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_concat
(
self
,
v
))
return
NULL
;
}
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_concat
(
self
,
v
));
else
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
self
,
v
));
else
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
v
))
return
NULL
;
}
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
v
));
return
m
;
}
...
...
@@ -2092,14 +2215,11 @@ subclass_repeat(PyObject *self, int v)
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__repeat__
))
return
NULL
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
repeat_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
UNLESS_ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_repeat
(
self
,
v
))
return
NULL
;
}
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_repeat
(
self
,
v
));
else
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"Oi"
,
self
,
v
));
else
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"i"
,
v
))
return
NULL
;
}
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"i"
,
v
));
return
m
;
}
...
...
@@ -2131,20 +2251,30 @@ subclass_subscript(PyObject *self, PyObject *key)
return
t
->
tp_as_mapping
->
mp_subscript
(
self
,
key
);
}
}
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
key
))
goto
err
;
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
self
,
key
));
else
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
key
));
return
m
;
err:
Py_DECREF
(
m
);
return
NULL
;
}
static
long
subclass_ass_subscript
(
PyObject
*
self
,
PyObject
*
index
,
PyObject
*
v
)
{
long
r
;
PyObject
*
m
;
PyExtensionClass
*
t
;
if
(
!
v
&&
(
m
=
subclass_getspecial
(
self
,
py__delitem__
)))
{
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
self
,
index
))
return
-
1
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
index
))
return
-
1
;
Py_DECREF
(
m
);
return
0
;
}
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__setitem__
))
return
-
1
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
setitem_by_name
...
...
@@ -2157,13 +2287,18 @@ subclass_ass_subscript(PyObject *self, PyObject *index, PyObject *v)
return
t
->
tp_as_mapping
->
mp_ass_subscript
(
self
,
index
,
v
);
}
}
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
index
,
v
))
return
-
1
;
r
=
PyInt_AsLong
(
m
);
Py_DECREF
(
m
);
return
r
;
err:
if
(
!
v
)
{
PyErr_SetObject
(
PyExc_AttributeError
,
py__delitem__
);
return
-
1
;
}
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OOO"
,
self
,
index
,
v
))
return
-
1
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
index
,
v
))
return
-
1
;
Py_DECREF
(
m
);
return
NULL
;
return
0
;
}
PyMappingMethods
subclass_as_mapping
=
{
...
...
@@ -2182,11 +2317,11 @@ dealloc_base(PyObject *inst, PyExtensionClass* self)
for
(
i
=
0
;
i
<
l
;
i
++
)
{
t
=
PyTuple_GET_ITEM
(
self
->
bases
,
i
);
if
(
Py
ExtensionClass_Check
(
t
))
if
(
ExtensionClass_Check
(
t
))
{
if
(
As
Py
ExtensionClass
(
t
)
->
bases
)
if
(
AsExtensionClass
(
t
)
->
bases
)
{
if
(
dealloc_base
(
inst
,
As
Py
ExtensionClass
(
t
)))
return
1
;
if
(
dealloc_base
(
inst
,
AsExtensionClass
(
t
)))
return
1
;
}
else
{
...
...
@@ -2206,11 +2341,29 @@ subclass_dealloc(PyObject *self)
{
PyObject
*
m
,
*
t
,
*
v
,
*
tb
;
#ifdef TRACE_DEALLOC
fprintf
(
stderr
,
"Deallocating a %s
\n
"
,
self
->
ob_type
->
tp_name
);
#endif
PyErr_Fetch
(
&
t
,
&
v
,
&
tb
);
Py_INCREF
(
self
);
/* Give us a new lease on life */
if
(
m
=
subclass_getspecial
(
self
,
py__del__
))
PyObject_CallFunction
(
m
,
""
);
{
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
self
));
else
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
""
));
Py_XDECREF
(
m
);
}
PyErr_Clear
();
if
(
--
self
->
ob_refcnt
>
0
)
{
PyErr_Restore
(
t
,
v
,
tb
);
return
;
/* we added a reference; don't delete now */
}
Py_XDECREF
(
INSTANCE_DICT
(
self
));
Py_DECREF
(
self
->
ob_type
);
...
...
@@ -2220,41 +2373,53 @@ subclass_dealloc(PyObject *self)
PyErr_Restore
(
t
,
v
,
tb
);
}
static
int
datafull_baseclasses
(
PyExtensionClass
*
type
)
static
void
datafull_baseclasses
f
(
PyExtensionClass
*
type
,
PyObject
**
c1
,
PyObject
**
c2
)
{
/* Find the number of classes that have data and return them.
There should be
only
one.
There should be
no more than
one.
*/
int
l
,
i
,
n
=
0
;
PyObject
*
base
;
typedef
struct
{
PyObject_HEAD
}
Dataless
;
l
=
PyTuple_Size
(
type
->
bases
);
for
(
i
=
0
;
i
<
l
;
i
++
)
for
(
i
=
0
;
i
<
l
&&
!
(
*
c1
&&
*
c2
)
;
i
++
)
{
base
=
PyTuple_GET_ITEM
(
type
->
bases
,
i
);
if
(
Py
ExtensionClass_Check
(
base
))
if
(
ExtensionClass_Check
(
base
))
{
if
(
As
Py
ExtensionClass
(
base
)
->
bases
)
n
+=
datafull_baseclasses
(
AsPyExtensionClass
(
base
)
);
if
(
AsExtensionClass
(
base
)
->
bases
)
datafull_baseclassesf
(
AsExtensionClass
(
base
),
c1
,
c2
);
else
{
if
(
AsPyExtensionClass
(
base
)
->
tp_basicsize
>
sizeof
(
Dataless
)
||
AsPyExtensionClass
(
base
)
->
tp_itemsize
>
0
)
n
++
;
if
(
AsExtensionClass
(
base
)
->
tp_basicsize
>
sizeof
(
PyPureMixinObject
)
||
AsExtensionClass
(
base
)
->
tp_itemsize
>
0
)
{
if
(
!
*
c1
)
*
c1
=
base
;
else
if
(
*
c1
!=
base
)
*
c2
=
base
;
}
}
}
}
return
n
;
}
static
int
datafull_baseclasses
(
PyExtensionClass
*
type
)
{
PyObject
*
c1
=
0
,
*
c2
=
0
;
datafull_baseclassesf
(
type
,
&
c1
,
&
c2
);
if
(
c2
)
return
2
;
if
(
c1
)
return
1
;
return
0
;
}
static
PyObject
*
datafull_baseclass
(
PyExtensionClass
*
type
)
{
/* Find the number of classes that have data and return them.
There should be only one.
*/
/* Find the baseclass that has data and. There should be only one. */
int
l
,
i
,
n
=
0
;
PyObject
*
base
,
*
dbase
;
...
...
@@ -2262,17 +2427,18 @@ datafull_baseclass(PyExtensionClass *type)
for
(
i
=
0
;
i
<
l
;
i
++
)
{
base
=
PyTuple_GET_ITEM
(
type
->
bases
,
i
);
if
(
Py
ExtensionClass_Check
(
base
))
if
(
ExtensionClass_Check
(
base
))
{
if
(
As
Py
ExtensionClass
(
base
)
->
bases
)
if
(
AsExtensionClass
(
base
)
->
bases
)
{
if
(
dbase
=
datafull_baseclass
(
As
Py
ExtensionClass
(
base
)))
if
(
dbase
=
datafull_baseclass
(
AsExtensionClass
(
base
)))
return
dbase
;
}
else
{
if
(
AsPyExtensionClass
(
base
)
->
tp_basicsize
>
sizeof
(
Dataless
)
||
AsPyExtensionClass
(
base
)
->
tp_itemsize
>
0
)
if
(
AsExtensionClass
(
base
)
->
tp_basicsize
>
sizeof
(
PyPureMixinObject
)
||
AsExtensionClass
(
base
)
->
tp_itemsize
>
0
)
return
base
;
}
}
...
...
@@ -2280,6 +2446,23 @@ datafull_baseclass(PyExtensionClass *type)
return
NULL
;
}
static
PyObject
*
extension_baseclass
(
PyExtensionClass
*
type
)
{
/* Find the first immediate base class that is an extension class */
int
l
,
i
,
n
=
0
;
PyObject
*
base
;
l
=
PyTuple_Size
(
type
->
bases
);
for
(
i
=
0
;
i
<
l
;
i
++
)
{
base
=
PyTuple_GET_ITEM
(
type
->
bases
,
i
);
if
(
ExtensionClass_Check
(
base
))
return
base
;
}
return
PyErr_Format
(
PyExc_TypeError
,
"No extension class found in subclass"
,
NULL
);
}
static
int
subclass_hasattr
(
PyExtensionClass
*
type
,
PyObject
*
name
)
{
...
...
@@ -2341,38 +2524,29 @@ subclass_init_getattr(PyExtensionClass *self, PyObject *methods)
{
PyObject
*
m
;
if
((
m
=
CCL_getattr
(
self
,
py__getattr__
,
"__getattr__"
)))
if
((
m
=
CCL_getattr
(
self
,
py__getattr__
,
0
)))
{
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
getattr_by_name
&&
Subclass_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
self
->
tp_getattr
=
AsCMethod
(
m
)
->
type
->
tp_getattr
;
}
#if PYTHON_API_VERSION >= 1005
else
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
getattro_by_name
&&
Subclass_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
self
->
tp_getattro
=
AsCMethod
(
m
)
->
type
->
tp_getattro
;
}
#endif
else
{
PyDict_SetItem
(
methods
,
py__getattr__
,
m
);
#if PYTHON_API_VERSION >= 1005
PyObject_SetItem
(
methods
,
py__getattr__
,
m
);
self
->
tp_getattro
=
subclass_getattro
;
#else
self
->
tp_getattr
=
subclass_getattr
;
#endif
}
Py_DECREF
(
m
);
}
else
{
PyErr_Clear
();
#if PYTHON_API_VERSION >= 1005
self
->
tp_getattro
=
EC_findiattro
;
#else
self
->
tp_getattr
=
EC_findiattrs
;
#endif
}
}
...
...
@@ -2381,41 +2555,58 @@ subclass_init_setattr(PyExtensionClass *self, PyObject *methods)
{
PyObject
*
m
;
if
((
m
=
CCL_getattr
(
self
,
py__setattr__
,
"__setattr__"
)))
if
((
m
=
CCL_getattr
(
self
,
py__setattr__
,
0
)))
{
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
setattr_by_name
&&
Subclass_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
self
->
tp_setattr
=
AsCMethod
(
m
)
->
type
->
tp_setattr
;
}
#if PYTHON_API_VERSION >= 1005
else
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
setattro_by_name
&&
Subclass_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
self
->
tp_setattro
=
AsCMethod
(
m
)
->
type
->
tp_setattro
;
}
#endif
else
{
PyDict_SetItem
(
methods
,
py__setattr__
,
m
);
#if PYTHON_API_VERSION >= 1005
PyObject_SetItem
(
methods
,
py__setattr__
,
m
);
self
->
tp_setattro
=
subclass_setattro
;
#else
self
->
tp_setattr
=
subclass_setattr
;
#endif
}
Py_DECREF
(
m
);
}
else
{
PyErr_Clear
();
#if PYTHON_API_VERSION >= 1005
self
->
tp_setattro
=
subclass_simple_setattro
;
#else
self
->
tp_setattro
=
subclass_simple_setattr
;
#endif
}
}
static
PyObject
*
CopyMethods
(
PyExtensionClass
*
type
,
PyObject
*
base_methods
)
{
PyObject
*
methods
,
*
key
,
*
v
;
int
pos
;
UNLESS
(
type
->
class_dictionary
&&
PyDict_Check
(
base_methods
)
&&
ExtensionInstance_Check
(
type
->
class_dictionary
))
{
Py_INCREF
(
base_methods
);
return
base_methods
;
}
UNLESS
(
methods
=
PyObject_CallObject
((
PyObject
*
)
type
->
class_dictionary
->
ob_type
,
NULL
))
return
NULL
;
for
(
pos
=
0
;
PyDict_Next
(
base_methods
,
&
pos
,
&
key
,
&
v
);
)
UNLESS
(
0
<=
PyObject_SetItem
(
methods
,
key
,
v
))
goto
err
;
return
methods
;
err:
Py_DECREF
(
methods
);
return
NULL
;
}
/* Constructor for building subclasses of C classes.
...
...
@@ -2427,10 +2618,14 @@ subclass__init__(PyExtensionClass *self, PyObject *args)
{
PyObject
*
bases
,
*
methods
,
*
class_init
;
PyExtensionClass
*
type
;
char
*
name
;
int
dynamic
=
1
;
char
*
name
,
*
p
;
int
dynamic
=
1
,
l
;
UNLESS
(
PyArg_Parse
(
args
,
"(sOO)"
,
&
name
,
&
bases
,
&
methods
))
return
NULL
;
l
=
strlen
(
name
)
+
1
;
UNLESS
(
p
=
(
char
*
)
malloc
(
l
*
sizeof
(
char
)))
return
PyErr_NoMemory
();
memcpy
(
p
,
name
,
l
);
name
=
p
;
UNLESS
(
PyTuple_Check
(
bases
)
&&
PyTuple_Size
(
bases
))
{
...
...
@@ -2448,12 +2643,13 @@ subclass__init__(PyExtensionClass *self, PyObject *args)
return
NULL
;
}
UNLESS
(
type
=
(
PyExtensionClass
*
)
datafull_baseclass
(
self
))
type
=
(
PyExtensionClass
*
)
PyTuple_GET_ITEM
(
bases
,
0
);
UNLESS
(
type
=
(
PyExtensionClass
*
)
extension_baseclass
(
self
))
return
NULL
;
self
->
tp_name
=
name
;
self
->
bases
=
bases
;
Py_INCREF
(
methods
)
;
self
->
class_dictionary
=
methods
;
UNLESS
(
self
->
class_dictionary
=
CopyMethods
(
type
,
methods
))
return
NULL
;
#define copy_member(M) self->M=type->M
copy_member
(
ob_size
);
copy_member
(
class_flags
);
...
...
@@ -2481,19 +2677,28 @@ subclass__init__(PyExtensionClass *self, PyObject *args)
subclass_set
(
compare
,
cmp
);
subclass_set
(
repr
,
repr
);
if
(
subclass_hasattr
(
self
,
py__bind_to_object__
)
&&
subclass_hasattr
(
self
,
py__call__
))
if
(
subclass_hasattr
(
self
,
py__of__
))
self
->
class_flags
|=
EXTENSIONCLASS_BINDABLE_FLAG
;
if
(
dynamic
||
has_number_methods
(
self
))
self
->
tp_as_number
=&
subclass_as_number
;
{
self
->
tp_as_number
=
(
PyNumberMethods
*
)
malloc
(
sizeof
(
PyNumberMethods
));
UNLESS
(
self
->
tp_as_number
)
return
PyErr_NoMemory
();
*
(
self
->
tp_as_number
)
=
subclass_as_number
;
}
else
self
->
tp_as_number
=
NULL
;
if
(
dynamic
||
has_collection_methods
(
self
))
{
self
->
tp_as_sequence
=&
subclass_as_sequence
;
self
->
tp_as_mapping
=&
subclass_as_mapping
;
self
->
tp_as_sequence
=
(
PySequenceMethods
*
)
malloc
(
sizeof
(
PySequenceMethods
));
UNLESS
(
self
->
tp_as_sequence
)
return
PyErr_NoMemory
();
*
(
self
->
tp_as_sequence
)
=
subclass_as_sequence
;
self
->
tp_as_mapping
=
(
PyMappingMethods
*
)
malloc
(
sizeof
(
PyMappingMethods
));
UNLESS
(
self
->
tp_as_mapping
)
return
PyErr_NoMemory
();
*
(
self
->
tp_as_mapping
)
=
subclass_as_mapping
;
}
else
{
...
...
@@ -2506,11 +2711,9 @@ subclass__init__(PyExtensionClass *self, PyObject *args)
self
->
tp_doc
=
0
;
/* Check for and use __class_init__ */
if
(
class_init
=
PyObject_GetAttrString
(
AsPyObject
(
self
),
"
__class
_init__"
))
if
(
class_init
=
PyObject_GetAttrString
(
AsPyObject
(
self
),
"
class_
_init__"
))
{
UNLESS_ASSIGN
(
class_init
,
PyObject_GetAttrString
(
class_init
,
"im_func"
))
return
NULL
;
UNLESS_ASSIGN
(
class_init
,
PyObject_CallFunction
(
class_init
,
"O"
,
self
))
UNLESS_ASSIGN
(
class_init
,
PyObject_CallObject
(
class_init
,
NULL
))
return
NULL
;
Py_DECREF
(
class_init
);
}
...
...
@@ -2527,18 +2730,17 @@ struct PyMethodDef ExtensionClass_methods[] = {
{
NULL
,
NULL
}
/* sentinel */
};
static
PyExtensionClass
CCLtype
=
{
PyObject_HEAD_INIT
(
&
CCLtype_class
)
static
PyExtensionClass
ECType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"
C Class"
,
/*tp_name*/
"
ExtensionClass"
,
/*tp_name*/
sizeof
(
PyExtensionClass
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
CCL_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
CCL_getattrs
,
/*tp_getattr*/
(
setattrfunc
)
CCL_setattrs
,
/*tp_setattr*/
(
getattrfunc
)
0
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
CCL_repr
,
/*tp_repr*/
0
,
/*tp_as_number*/
...
...
@@ -2547,149 +2749,50 @@ static PyExtensionClass CCLtype = {
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
CCL_call
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
#if PYTHON_API_VERSION >= 1005
(
getattrofunc
)
CCL_getattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
CCL_setattro
,
/*tp_setattr with object key*/
#else
/* Space for future expansion */
0L
,
0L
,
#endif
0L
,
0L
,
"C classes"
,
/* Documentation string */
METHOD_CHAIN
(
ExtensionClass_methods
)
};
static
PyExtensionClass
Basetype
=
{
PyObject_HEAD_INIT
(
&
PyType_Type
)
0
,
/*ob_size*/
"Base"
,
/*tp_name*/
sizeof
(
Dataless
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
0
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
EC_findiattrs
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
0
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
#if PYTHON_API_VERSION >= 1005
(
getattrofunc
)
EC_findiattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
0
,
/*tp_setattr with object key*/
#else
/* Space for future expansion */
0L
,
0L
,
#endif
0L
,
0L
,
"Base -- a do nothing base class
\n
"
"
\n
"
"A trivial base class that doesn't have any inheritable
\n
"
"attributes but that can be listed first in the set of superclasses
\n
"
"of a new subclass.
\n
"
,
{
NULL
,
NULL
}
};
static
PyObject
*
bind_to_object
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
inst
;
PMethod
*
r
;
UNLESS
(
PyArg_Parse
(
args
,
"O"
,
&
inst
))
return
NULL
;
UNLESS
(
PyExtensionInstance_Check
(
inst
))
{
PyErr_SetString
(
PyExc_TypeError
,
"attempt to wrap extension method using an object that
\n
"
"is not an extension class instance."
);
return
NULL
;
}
UNLESS
(
r
=
PyObject_NEW
(
PMethod
,
&
PMethodType
))
return
NULL
;
Py_INCREF
(
inst
);
Py_INCREF
(
inst
->
ob_type
);
r
->
type
=
inst
->
ob_type
;
r
->
self
=
inst
;
r
->
meth
=
self
;
return
AsPyObject
(
r
);
}
struct
PyMethodDef
Method_methods
[]
=
{
{
"__bind_to_object__"
,(
PyCFunction
)
bind_to_object
,
0
,
""
},
{
NULL
,
NULL
}
/* sentinel */
};
static
PyExtensionClass
Methodtype
=
{
PyObject_HEAD_INIT
(
&
PyType_Type
)
0
,
/*ob_size*/
"Method"
,
/*tp_name*/
sizeof
(
Dataless
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
0
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
EC_findiattrs
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
0
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
#if PYTHON_API_VERSION >= 1005
(
getattrofunc
)
EC_findiattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
0
,
/*tp_setattr with object key*/
#else
/* Space for future expansion */
0L
,
0L
,
#endif
0L
,
0L
,
"Base class for objects that want to be treated as methods
\n
"
"
\n
"
"The method class provides a method, __bind_to_object__, that
\n
"
"binds an object to an instance. If a method is a subobject
\n
"
"of an extension-class instance, the the method will be bound
\n
"
"to the instance and when the resulting object is called, it
\n
"
"will call the method and pass the instance in addition to
\n
"
"other arguments. It is the responsibility of Method objects
\n
"
"to implement (or inherit) a __call__ method.
\n
"
,
METHOD_CHAIN
(
Method_methods
)
};
PyObject
*
MetaTypeUndefinedMethod
()
{
PyErr_SetString
(
PyExc_TypeError
,
"undefined operation on partially numeric PyObject"
);
return
NULL
;
}
/* List of methods defined in the module */
static
struct
PyMethodDef
CC_methods
[]
=
{
{
NULL
,
NULL
}
/* sentinel */
{
NULL
,
NULL
}
/* sentinel */
};
static
int
export_type
(
PyObject
*
dict
,
char
*
name
,
PyExtensionClass
*
typ
)
{
initializeBaseExtensionClass
(
typ
);
return
PyMapping_SetItemString
(
dict
,
name
,(
PyObject
*
)
typ
);
}
static
struct
ExtensionClassCAPIstruct
TrueExtensionClassCAPI
=
{
export_type
,
EC_findiattrs
,
EC_findiattro
,
subclass_simple_setattr
,
subclass_simple_setattro
,
(
PyObject
*
)
&
ECType
,
(
PyObject
*
)
&
PMethodType
,
PMethod_New
,
};
void
initExtensionClass
()
{
PyObject
*
m
,
*
d
;
PURE_MIXIN_CLASS
(
Base
,
"Minimalbase class for Extension Classes"
,
NULL
);
PMethodType
.
ob_type
=&
PyType_Type
;
CMethodType
.
ob_type
=&
PyType_Type
;
ECTypeType
.
ob_type
=&
PyType_Type
;
ECType
.
ob_type
=&
ECTypeType
;
/* Create the module and add the functions */
m
=
Py_InitModule4
(
"ExtensionClass"
,
CC_methods
,
ExtensionClass_module_documentation
,
...
...
@@ -2700,28 +2803,19 @@ initExtensionClass()
init_py_names
();
initializeBaseExtensionClass
(
&
CCLt
ype
);
PyDict_SetItemString
(
d
,
"ExtensionClass
Type"
,
(
PyObject
*
)
&
CCLt
ype
);
initializeBaseExtensionClass
(
&
ECT
ype
);
PyDict_SetItemString
(
d
,
"ExtensionClass
"
,
(
PyObject
*
)
&
ECT
ype
);
initializeBaseExtensionClass
(
&
Base
t
ype
);
PyDict_SetItemString
(
d
,
"Base"
,
(
PyObject
*
)
&
Base
t
ype
);
initializeBaseExtensionClass
(
&
Base
T
ype
);
PyDict_SetItemString
(
d
,
"Base"
,
(
PyObject
*
)
&
Base
T
ype
);
initializeBaseExtensionClass
(
&
Methodt
ype
);
PyDict_SetItemString
(
d
,
"
Method"
,
(
PyObject
*
)
&
Methodt
ype
);
PyDict_SetItemString
(
d
,
"PythonMethodType"
,
(
PyObject
*
)
&
PMethodT
ype
);
PyDict_SetItemString
(
d
,
"
ExtensionMethodType"
,
(
PyObject
*
)
&
CMethodT
ype
);
#ifdef Py_COBJECT_H
/* Export C attribute lookup API */
PyDict_SetItemString
(
d
,
"_PyEC_getattrs"
,
PyCObject_FromVoidPtr
(
EC_findiattrs
,
NULL
));
PyDict_SetItemString
(
d
,
"_PyEC_getattro"
,
PyCObject_FromVoidPtr
(
EC_findiattro
,
NULL
));
PyDict_SetItemString
(
d
,
"_PyEC_setattrs"
,
PyCObject_FromVoidPtr
(
subclass_simple_setattr
,
NULL
));
PyDict_SetItemString
(
d
,
"_PyEC_setattro"
,
PyCObject_FromVoidPtr
(
subclass_simple_setattro
,
NULL
));
#endif
PyExtensionClassCAPI
=&
TrueExtensionClassCAPI
;
PyDict_SetItemString
(
d
,
"CAPI"
,
PyCObject_FromVoidPtr
(
PyExtensionClassCAPI
,
NULL
));
/* Check for errors */
if
(
PyErr_Occurred
())
Py_FatalError
(
"can't initialize module ExtensionClass"
);
CHECK_FOR_ERRORS
(
"can't initialize module ExtensionClass"
);
}
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