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
f2637647
Commit
f2637647
authored
Feb 20, 2001
by
Jim Fulton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
moved source files to src directory
parent
7dbb8830
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
0 additions
and
7546 deletions
+0
-7546
lib/Components/ExtensionClass/Acquisition.c
lib/Components/ExtensionClass/Acquisition.c
+0
-1466
lib/Components/ExtensionClass/ComputedAttribute.c
lib/Components/ExtensionClass/ComputedAttribute.c
+0
-166
lib/Components/ExtensionClass/ExtensionClass.c
lib/Components/ExtensionClass/ExtensionClass.c
+0
-3570
lib/Components/ExtensionClass/ExtensionClass.h
lib/Components/ExtensionClass/ExtensionClass.h
+0
-453
lib/Components/ExtensionClass/MethodObject.c
lib/Components/ExtensionClass/MethodObject.c
+0
-97
lib/Components/ExtensionClass/Missing.c
lib/Components/ExtensionClass/Missing.c
+0
-377
lib/Components/ExtensionClass/MultiMapping.c
lib/Components/ExtensionClass/MultiMapping.c
+0
-251
lib/Components/ExtensionClass/Record.c
lib/Components/ExtensionClass/Record.c
+0
-694
lib/Components/ExtensionClass/Sync.c
lib/Components/ExtensionClass/Sync.c
+0
-147
lib/Components/ExtensionClass/ThreadLock.c
lib/Components/ExtensionClass/ThreadLock.c
+0
-325
No files found.
lib/Components/ExtensionClass/Acquisition.c
deleted
100644 → 0
View file @
7dbb8830
/*
Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
o Redistributions of source code must retain the above copyright
notice, this list of conditions, and the disclaimer that follows.
o Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
o Neither the name of Digital Creations nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
$Id: Acquisition.c,v 1.47 2001/02/19 19:16:07 jeremy Exp $
If you have questions regarding this software,
contact:
Digital Creations L.C.
info@digicool.com
(540) 371-6909
*/
#include "ExtensionClass.h"
static
void
PyVar_Assign
(
PyObject
**
v
,
PyObject
*
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 OBJECT(O) ((PyObject*)(O))
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__invert__
,
*
py__int__
,
*
py__long__
,
*
py__float__
,
*
py__oct__
,
*
py__hex__
,
*
py__getitem__
,
*
py__setitem__
,
*
py__delitem__
,
*
py__getslice__
,
*
py__setslice__
,
*
py__delslice__
,
*
py__len__
,
*
py__of__
,
*
py__call__
,
*
py__repr__
,
*
py__str__
,
*
py__cmp__
;
static
PyObject
*
Acquired
=
0
;
static
void
init_py_names
()
{
#define INIT_PY_NAME(N) py ## N = PyString_FromString(#N)
INIT_PY_NAME
(
__add__
);
INIT_PY_NAME
(
__sub__
);
INIT_PY_NAME
(
__mul__
);
INIT_PY_NAME
(
__div__
);
INIT_PY_NAME
(
__mod__
);
INIT_PY_NAME
(
__pow__
);
INIT_PY_NAME
(
__divmod__
);
INIT_PY_NAME
(
__lshift__
);
INIT_PY_NAME
(
__rshift__
);
INIT_PY_NAME
(
__and__
);
INIT_PY_NAME
(
__or__
);
INIT_PY_NAME
(
__xor__
);
INIT_PY_NAME
(
__coerce__
);
INIT_PY_NAME
(
__neg__
);
INIT_PY_NAME
(
__pos__
);
INIT_PY_NAME
(
__abs__
);
INIT_PY_NAME
(
__nonzero__
);
INIT_PY_NAME
(
__invert__
);
INIT_PY_NAME
(
__int__
);
INIT_PY_NAME
(
__long__
);
INIT_PY_NAME
(
__float__
);
INIT_PY_NAME
(
__oct__
);
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
(
__len__
);
INIT_PY_NAME
(
__of__
);
INIT_PY_NAME
(
__call__
);
INIT_PY_NAME
(
__repr__
);
INIT_PY_NAME
(
__str__
);
INIT_PY_NAME
(
__cmp__
);
#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
))
{
if
(
args
)
{
Py_DECREF
(
args
);
}
return
NULL
;
}
ASSIGN
(
name
,
PyEval_CallObjectWithKeywords
(
name
,
args
,
kw
));
if
(
args
)
{
Py_DECREF
(
args
);
}
return
name
;
}
#define Build Py_BuildValue
/* Declarations for objects of type Wrapper */
typedef
struct
{
PyObject_HEAD
PyObject
*
obj
;
PyObject
*
container
;
}
Wrapper
;
staticforward
PyExtensionClass
Wrappertype
,
XaqWrappertype
;
#define isWrapper(O) ((O)->ob_type==(PyTypeObject*)&Wrappertype || \
(O)->ob_type==(PyTypeObject*)&XaqWrappertype)
#define WRAPPER(O) ((Wrapper*)(O))
static
PyObject
*
Wrapper__init__
(
Wrapper
*
self
,
PyObject
*
args
)
{
PyObject
*
obj
,
*
container
;
UNLESS
(
PyArg_Parse
(
args
,
"(OO)"
,
&
obj
,
&
container
))
return
NULL
;
Py_INCREF
(
obj
);
Py_INCREF
(
container
);
self
->
obj
=
obj
;
self
->
container
=
container
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
/* ---------------------------------------------------------------- */
static
PyObject
*
__of__
(
PyObject
*
inst
,
PyObject
*
parent
)
{
PyObject
*
r
,
*
t
;
UNLESS
(
r
=
PyObject_GetAttr
(
inst
,
py__of__
))
return
NULL
;
UNLESS
(
t
=
PyTuple_New
(
1
))
goto
err
;
PyTuple_SET_ITEM
(
t
,
0
,
parent
);
ASSIGN
(
r
,
PyObject_CallObject
(
r
,
t
));
PyTuple_SET_ITEM
(
t
,
0
,
NULL
);
Py_DECREF
(
t
);
if
(
r
&&
r
->
ob_refcnt
==
1
&&
isWrapper
(
r
)
&&
WRAPPER
(
r
)
->
container
&&
isWrapper
(
WRAPPER
(
r
)
->
container
)
)
while
(
WRAPPER
(
r
)
->
obj
&&
isWrapper
(
WRAPPER
(
r
)
->
obj
)
&&
(
WRAPPER
(
WRAPPER
(
r
)
->
obj
)
->
container
==
WRAPPER
(
WRAPPER
(
r
)
->
container
)
->
obj
)
)
{
/* Simplify wrapper */
Py_XINCREF
(
WRAPPER
(
WRAPPER
(
r
)
->
obj
)
->
obj
);
ASSIGN
(
WRAPPER
(
r
)
->
obj
,
WRAPPER
(
WRAPPER
(
r
)
->
obj
)
->
obj
);
}
return
r
;
err:
Py_DECREF
(
r
);
return
NULL
;
}
static
Wrapper
*
freeWrappers
=
0
;
static
int
nWrappers
=
0
;
#define MAX_CACHED_WRAPPERS 200
static
PyObject
*
newWrapper
(
PyObject
*
obj
,
PyObject
*
container
,
PyTypeObject
*
Wrappertype
)
{
Wrapper
*
self
;
if
(
freeWrappers
)
{
self
=
freeWrappers
;
freeWrappers
=
(
Wrapper
*
)
self
->
obj
;
self
->
ob_type
=
Wrappertype
;
self
->
ob_refcnt
=
1
;
nWrappers
--
;
}
else
{
UNLESS
(
self
=
PyObject_NEW
(
Wrapper
,
Wrappertype
))
return
NULL
;
}
Py_INCREF
(
Wrappertype
);
Py_XINCREF
(
obj
);
Py_XINCREF
(
container
);
self
->
obj
=
obj
;
self
->
container
=
container
;
return
OBJECT
(
self
);
}
static
void
Wrapper_dealloc
(
Wrapper
*
self
)
{
Py_XDECREF
(
self
->
obj
);
Py_XDECREF
(
self
->
container
);
Py_DECREF
(
self
->
ob_type
);
if
(
nWrappers
<
MAX_CACHED_WRAPPERS
)
{
self
->
obj
=
OBJECT
(
freeWrappers
);
freeWrappers
=
self
;
nWrappers
++
;
}
else
{
PyMem_DEL
(
self
);
}
}
static
PyObject
*
Wrapper_special
(
Wrapper
*
self
,
char
*
name
,
PyObject
*
oname
)
{
PyObject
*
r
=
0
;
switch
(
*
name
)
{
case
'b'
:
if
(
strcmp
(
name
,
"base"
)
==
0
)
{
if
(
self
->
obj
)
{
r
=
self
->
obj
;
while
(
isWrapper
(
r
)
&&
WRAPPER
(
r
)
->
obj
)
r
=
WRAPPER
(
r
)
->
obj
;
}
else
r
=
Py_None
;
Py_INCREF
(
r
);
return
r
;
}
break
;
case
'p'
:
if
(
strcmp
(
name
,
"parent"
)
==
0
)
{
if
(
self
->
container
)
r
=
self
->
container
;
else
r
=
Py_None
;
Py_INCREF
(
r
);
return
r
;
}
break
;
case
's'
:
if
(
strcmp
(
name
,
"self"
)
==
0
)
{
if
(
self
->
obj
)
r
=
self
->
obj
;
else
r
=
Py_None
;
Py_INCREF
(
r
);
return
r
;
}
break
;
case
'e'
:
if
(
strcmp
(
name
,
"explicit"
)
==
0
)
{
if
(
self
->
ob_type
!=
(
PyTypeObject
*
)
&
XaqWrappertype
)
return
newWrapper
(
self
->
obj
,
self
->
container
,
(
PyTypeObject
*
)
&
XaqWrappertype
);
Py_INCREF
(
self
);
return
OBJECT
(
self
);
}
break
;
case
'a'
:
if
(
strcmp
(
name
,
"acquire"
)
==
0
)
{
return
Py_FindAttr
(
OBJECT
(
self
),
oname
);
}
break
;
case
'c'
:
if
(
strcmp
(
name
,
"chain"
)
==
0
)
{
if
((
r
=
PyList_New
(
0
)))
while
(
1
)
{
if
(
PyList_Append
(
r
,
OBJECT
(
self
))
>=
0
)
{
if
(
isWrapper
(
self
)
&&
self
->
container
)
{
self
=
WRAPPER
(
self
->
container
);
continue
;
}
}
else
{
Py_DECREF
(
r
);
}
break
;
}
return
r
;
}
break
;
case
'i'
:
if
(
strcmp
(
name
,
"inContextOf"
)
==
0
)
{
return
Py_FindAttr
(
OBJECT
(
self
),
oname
);
}
if
(
strcmp
(
name
,
"inner"
)
==
0
)
{
if
(
self
->
obj
)
{
r
=
self
->
obj
;
while
(
isWrapper
(
r
)
&&
WRAPPER
(
r
)
->
obj
)
{
self
=
WRAPPER
(
r
);
r
=
WRAPPER
(
r
)
->
obj
;
}
r
=
OBJECT
(
self
);
}
else
r
=
Py_None
;
Py_INCREF
(
r
);
return
r
;
}
break
;
case
'u'
:
if
(
strcmp
(
name
,
"uncle"
)
==
0
)
{
return
PyString_FromString
(
"Bob"
);
}
break
;
}
return
NULL
;
}
static
int
apply_filter
(
PyObject
*
filter
,
PyObject
*
inst
,
PyObject
*
oname
,
PyObject
*
r
,
PyObject
*
extra
,
PyObject
*
orig
)
{
PyObject
*
fr
;
int
ir
;
UNLESS
(
fr
=
PyTuple_New
(
5
))
goto
err
;
PyTuple_SET_ITEM
(
fr
,
0
,
orig
);
Py_INCREF
(
orig
);
PyTuple_SET_ITEM
(
fr
,
1
,
inst
);
Py_INCREF
(
inst
);
PyTuple_SET_ITEM
(
fr
,
2
,
oname
);
Py_INCREF
(
oname
);
PyTuple_SET_ITEM
(
fr
,
3
,
r
);
Py_INCREF
(
r
);
PyTuple_SET_ITEM
(
fr
,
4
,
extra
);
Py_INCREF
(
extra
);
UNLESS_ASSIGN
(
fr
,
PyObject_CallObject
(
filter
,
fr
))
goto
err
;
ir
=
PyObject_IsTrue
(
fr
);
Py_DECREF
(
fr
);
if
(
ir
)
return
1
;
Py_DECREF
(
r
);
return
0
;
err:
Py_DECREF
(
r
);
return
-
1
;
}
static
PyObject
*
Wrapper_acquire
(
Wrapper
*
self
,
PyObject
*
oname
,
PyObject
*
filter
,
PyObject
*
extra
,
PyObject
*
orig
,
int
explicit
,
int
containment
);
static
PyObject
*
Wrapper_findattr
(
Wrapper
*
self
,
PyObject
*
oname
,
PyObject
*
filter
,
PyObject
*
extra
,
PyObject
*
orig
,
int
sob
,
int
sco
,
int
explicit
,
int
containment
)
{
PyObject
*
r
,
*
v
,
*
tb
;
char
*
name
=
""
;
if
(
PyString_Check
(
oname
))
name
=
PyString_AS_STRING
(
oname
);
if
(
*
name
==
'a'
&&
name
[
1
]
==
'q'
&&
name
[
2
]
==
'_'
)
if
((
r
=
Wrapper_special
(
self
,
name
+
3
,
oname
)))
{
if
(
filter
)
switch
(
apply_filter
(
filter
,
OBJECT
(
self
),
oname
,
r
,
extra
,
orig
))
{
case
-
1
:
return
NULL
;
case
1
:
return
r
;
}
else
return
r
;
}
else
PyErr_Clear
();
else
if
(
*
name
==
'_'
&&
name
[
1
]
==
'_'
&&
strcmp
(
name
+
2
,
"reduce__"
)
==
0
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Can't pickle objects in acquisition wrappers."
);
return
NULL
;
}
/* If we are doing a containment search, then replace self with aq_inner */
if
(
containment
)
while
(
self
->
obj
&&
isWrapper
(
self
->
obj
))
self
=
WRAPPER
(
self
->
obj
);
if
(
sob
&&
self
->
obj
)
{
if
(
isWrapper
(
self
->
obj
))
{
if
((
r
=
Wrapper_findattr
(
WRAPPER
(
self
->
obj
),
oname
,
filter
,
extra
,
orig
,
1
,
/* Search object container if explicit,
or object is implicit acquirer */
explicit
||
self
->
obj
->
ob_type
==
(
PyTypeObject
*
)
&
Wrappertype
,
explicit
,
containment
)))
{
if
(
PyECMethod_Check
(
r
)
&&
PyECMethod_Self
(
r
)
==
self
->
obj
)
ASSIGN
(
r
,
PyECMethod_New
(
r
,
OBJECT
(
self
)));
else
if
(
has__of__
(
r
))
ASSIGN
(
r
,
__of__
(
r
,
OBJECT
(
self
)));
return
r
;
}
PyErr_Fetch
(
&
r
,
&
v
,
&
tb
);
if
(
r
&&
(
r
!=
PyExc_AttributeError
))
{
PyErr_Restore
(
r
,
v
,
tb
);
return
NULL
;
}
Py_XDECREF
(
r
);
Py_XDECREF
(
v
);
Py_XDECREF
(
tb
);
r
=
NULL
;
}
else
if
((
r
=
PyObject_GetAttr
(
self
->
obj
,
oname
)))
{
if
(
r
==
Acquired
)
{
Py_DECREF
(
r
);
return
Wrapper_acquire
(
self
,
oname
,
filter
,
extra
,
orig
,
1
,
containment
);
}
if
(
PyECMethod_Check
(
r
)
&&
PyECMethod_Self
(
r
)
==
self
->
obj
)
ASSIGN
(
r
,
PyECMethod_New
(
r
,
OBJECT
(
self
)));
else
if
(
has__of__
(
r
))
ASSIGN
(
r
,
__of__
(
r
,
OBJECT
(
self
)));
if
(
filter
)
switch
(
apply_filter
(
filter
,
OBJECT
(
self
),
oname
,
r
,
extra
,
orig
))
{
case
-
1
:
return
NULL
;
case
1
:
return
r
;
}
else
return
r
;
}
else
{
PyErr_Fetch
(
&
r
,
&
v
,
&
tb
);
if
(
r
!=
PyExc_AttributeError
)
{
PyErr_Restore
(
r
,
v
,
tb
);
return
NULL
;
}
Py_XDECREF
(
r
);
Py_XDECREF
(
v
);
Py_XDECREF
(
tb
);
r
=
NULL
;
}
PyErr_Clear
();
}
if
(
sco
&&
(
*
name
!=
'_'
||
explicit
))
return
Wrapper_acquire
(
self
,
oname
,
filter
,
extra
,
orig
,
explicit
,
containment
);
PyErr_SetObject
(
PyExc_AttributeError
,
oname
);
return
NULL
;
}
static
PyObject
*
Wrapper_acquire
(
Wrapper
*
self
,
PyObject
*
oname
,
PyObject
*
filter
,
PyObject
*
extra
,
PyObject
*
orig
,
int
explicit
,
int
containment
)
{
PyObject
*
r
;
int
sob
=
1
,
sco
=
1
;
if
(
self
->
container
)
{
if
(
isWrapper
(
self
->
container
))
{
if
(
self
->
obj
&&
isWrapper
(
self
->
obj
))
{
/* Try to optimize search by recognizing repeated obs in path */
if
(
WRAPPER
(
self
->
obj
)
->
container
==
WRAPPER
(
self
->
container
)
->
container
)
sco
=
0
;
else
if
(
WRAPPER
(
self
->
obj
)
->
container
==
WRAPPER
(
self
->
container
)
->
obj
)
sob
=
0
;
}
r
=
Wrapper_findattr
((
Wrapper
*
)
self
->
container
,
oname
,
filter
,
extra
,
orig
,
sob
,
sco
,
explicit
,
containment
);
if
(
r
&&
has__of__
(
r
))
ASSIGN
(
r
,
__of__
(
r
,
OBJECT
(
self
)));
return
r
;
}
else
{
if
((
r
=
PyObject_GetAttr
(
self
->
container
,
oname
)))
{
if
(
r
==
Acquired
)
{
Py_DECREF
(
r
);
}
else
{
if
(
filter
)
switch
(
apply_filter
(
filter
,
self
->
container
,
oname
,
r
,
extra
,
orig
))
{
case
-
1
:
return
NULL
;
case
1
:
if
(
has__of__
(
r
))
ASSIGN
(
r
,
__of__
(
r
,
OBJECT
(
self
)));
return
r
;
}
else
{
if
(
has__of__
(
r
))
ASSIGN
(
r
,
__of__
(
r
,
OBJECT
(
self
)));
return
r
;
}
}
}
}
}
PyErr_SetObject
(
PyExc_AttributeError
,
oname
);
return
NULL
;
}
static
PyObject
*
Wrapper_getattro
(
Wrapper
*
self
,
PyObject
*
oname
)
{
if
(
self
->
obj
||
self
->
container
)
return
Wrapper_findattr
(
self
,
oname
,
NULL
,
NULL
,
NULL
,
1
,
1
,
0
,
0
);
/* Maybe we are getting initialized? */
return
Py_FindAttr
(
OBJECT
(
self
),
oname
);
}
static
PyObject
*
Xaq_getattro
(
Wrapper
*
self
,
PyObject
*
oname
)
{
char
*
name
=
""
;
/* Special case backward-compatible acquire method. */
if
(
PyString_Check
(
oname
))
name
=
PyString_AS_STRING
(
oname
);
if
(
*
name
==
'a'
&&
name
[
1
]
==
'c'
&&
strcmp
(
name
+
2
,
"quire"
)
==
0
)
return
Py_FindAttr
(
OBJECT
(
self
),
oname
);
if
(
self
->
obj
||
self
->
container
)
return
Wrapper_findattr
(
self
,
oname
,
NULL
,
NULL
,
NULL
,
1
,
0
,
0
,
0
);
/* Maybe we are getting initialized? */
return
Py_FindAttr
(
OBJECT
(
self
),
oname
);
}
static
int
Wrapper_setattro
(
Wrapper
*
self
,
PyObject
*
oname
,
PyObject
*
v
)
{
char
*
name
=
""
;
/* Allow assignment to parent, to change context. */
if
(
PyString_Check
(
oname
))
name
=
PyString_AS_STRING
(
oname
);
if
(
*
name
==
'a'
&&
name
[
1
]
==
'q'
&&
name
[
2
]
==
'_'
&&
strcmp
(
name
+
3
,
"parent"
)
==
0
)
{
Py_XINCREF
(
v
);
ASSIGN
(
self
->
container
,
v
);
return
0
;
}
if
(
self
->
obj
)
{
/* Unwrap passed in wrappers! */
while
(
v
&&
isWrapper
(
v
))
v
=
WRAPPER
(
v
)
->
obj
;
if
(
v
)
return
PyObject_SetAttr
(
self
->
obj
,
oname
,
v
);
else
return
PyObject_DelAttr
(
self
->
obj
,
oname
);
}
PyErr_SetString
(
PyExc_AttributeError
,
"Attempt to set attribute on empty acquisition wrapper"
);
return
-
1
;
}
static
int
Wrapper_compare
(
Wrapper
*
self
,
PyObject
*
w
)
{
PyObject
*
obj
,
*
wobj
;
PyObject
*
m
;
int
r
;
if
(
OBJECT
(
self
)
==
w
)
return
0
;
UNLESS
(
m
=
PyObject_GetAttr
(
OBJECT
(
self
),
py__cmp__
))
{
/* Unwrap self completely -> obj. */
while
(
self
->
obj
&&
isWrapper
(
self
->
obj
))
self
=
WRAPPER
(
self
->
obj
);
obj
=
self
->
obj
;
/* Unwrap w completely -> wobj. */
if
(
isWrapper
(
w
))
{
while
(
WRAPPER
(
w
)
->
obj
&&
isWrapper
(
WRAPPER
(
w
)
->
obj
))
w
=
WRAPPER
(
w
)
->
obj
;
wobj
=
WRAPPER
(
w
)
->
obj
;
}
else
wobj
=
w
;
PyErr_Clear
();
if
(
obj
==
wobj
)
return
0
;
return
(
obj
<
w
)
?
-
1
:
1
;
}
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
w
));
UNLESS
(
m
)
return
-
1
;
r
=
PyInt_AsLong
(
m
);
Py_DECREF
(
m
);
return
r
;
}
static
PyObject
*
Wrapper_repr
(
Wrapper
*
self
)
{
PyObject
*
r
;
if
((
r
=
PyObject_GetAttr
(
OBJECT
(
self
),
py__repr__
)))
{
ASSIGN
(
r
,
PyObject_CallFunction
(
r
,
NULL
,
NULL
));
return
r
;
}
else
{
PyErr_Clear
();
return
PyObject_Repr
(
self
->
obj
);
}
}
static
PyObject
*
Wrapper_str
(
Wrapper
*
self
)
{
PyObject
*
r
;
if
((
r
=
PyObject_GetAttr
(
OBJECT
(
self
),
py__str__
)))
{
ASSIGN
(
r
,
PyObject_CallFunction
(
r
,
NULL
,
NULL
));
return
r
;
}
else
{
PyErr_Clear
();
return
PyObject_Str
(
self
->
obj
);
}
}
static
long
Wrapper_hash
(
Wrapper
*
self
)
{
return
PyObject_Hash
(
self
->
obj
);
}
static
PyObject
*
Wrapper_call
(
Wrapper
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
Py_INCREF
(
args
);
return
CallMethodO
(
OBJECT
(
self
),
py__call__
,
args
,
kw
);
}
/* Code to handle accessing Wrapper objects as sequence objects */
static
int
Wrapper_length
(
Wrapper
*
self
)
{
long
l
;
PyObject
*
r
;
UNLESS
(
r
=
PyObject_GetAttr
(
OBJECT
(
self
),
py__len__
))
{
/* Hm. Maybe we are being checked to see if we are true.
Check to see if we have a __getitem__. If we don't, then
answer that we are true, otherwise raise an error.
*/
PyErr_Clear
();
if
((
r
=
PyObject_GetAttr
(
OBJECT
(
self
),
py__getitem__
)))
{
/* Hm, we have getitem, must be error */
Py_DECREF
(
r
);
PyErr_SetObject
(
PyExc_AttributeError
,
py__len__
);
return
-
1
;
}
PyErr_Clear
();
/* Try nonzero */
UNLESS
(
r
=
PyObject_GetAttr
(
OBJECT
(
self
),
py__nonzero__
))
{
/* No nonzero, it's true :-) */
PyErr_Clear
();
return
1
;
}
}
UNLESS_ASSIGN
(
r
,
PyObject_CallObject
(
r
,
NULL
))
return
-
1
;
l
=
PyInt_AsLong
(
r
);
Py_DECREF
(
r
);
return
l
;
}
static
PyObject
*
Wrapper_add
(
Wrapper
*
self
,
PyObject
*
bb
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__add__
,
Build
(
"(O)"
,
bb
)
,
NULL
);
}
static
PyObject
*
Wrapper_mul
(
Wrapper
*
self
,
int
n
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__mul__
,
Build
(
"(i)"
,
n
),
NULL
);
}
static
PyObject
*
Wrapper_item
(
Wrapper
*
self
,
int
i
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__getitem__
,
Build
(
"(i)"
,
i
),
NULL
);
}
static
PyObject
*
Wrapper_slice
(
Wrapper
*
self
,
int
ilow
,
int
ihigh
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__getslice__
,
Build
(
"(ii)"
,
ilow
,
ihigh
),
NULL
);
}
static
int
Wrapper_ass_item
(
Wrapper
*
self
,
int
i
,
PyObject
*
v
)
{
if
(
v
)
{
UNLESS
(
v
=
CallMethodO
(
OBJECT
(
self
),
py__setitem__
,
Build
(
"(iO)"
,
i
,
v
),
NULL
))
return
-
1
;
}
else
{
UNLESS
(
v
=
CallMethodO
(
OBJECT
(
self
),
py__delitem__
,
Build
(
"(i)"
,
i
),
NULL
))
return
-
1
;
}
Py_DECREF
(
v
);
return
0
;
}
static
int
Wrapper_ass_slice
(
Wrapper
*
self
,
int
ilow
,
int
ihigh
,
PyObject
*
v
)
{
if
(
v
)
{
UNLESS
(
v
=
CallMethodO
(
OBJECT
(
self
),
py__setslice__
,
Build
(
"(iiO)"
,
ilow
,
ihigh
,
v
),
NULL
))
return
-
1
;
}
else
{
UNLESS
(
v
=
CallMethodO
(
OBJECT
(
self
),
py__delslice__
,
Build
(
"(ii)"
,
ilow
,
ihigh
),
NULL
))
return
-
1
;
}
Py_DECREF
(
v
);
return
0
;
}
static
PySequenceMethods
Wrapper_as_sequence
=
{
(
inquiry
)
Wrapper_length
,
/*sq_length*/
(
binaryfunc
)
Wrapper_add
,
/*sq_concat*/
(
intargfunc
)
Wrapper_mul
,
/*sq_repeat*/
(
intargfunc
)
Wrapper_item
,
/*sq_item*/
(
intintargfunc
)
Wrapper_slice
,
/*sq_slice*/
(
intobjargproc
)
Wrapper_ass_item
,
/*sq_ass_item*/
(
intintobjargproc
)
Wrapper_ass_slice
,
/*sq_ass_slice*/
};
/* -------------------------------------------------------------- */
/* Code to access Wrapper objects as mappings */
static
PyObject
*
Wrapper_subscript
(
Wrapper
*
self
,
PyObject
*
key
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__getitem__
,
Build
(
"(O)"
,
key
),
NULL
);
}
static
int
Wrapper_ass_sub
(
Wrapper
*
self
,
PyObject
*
key
,
PyObject
*
v
)
{
if
(
v
)
{
UNLESS
(
v
=
CallMethodO
(
OBJECT
(
self
),
py__setitem__
,
Build
(
"(OO)"
,
key
,
v
),
NULL
))
return
-
1
;
}
else
{
UNLESS
(
v
=
CallMethodO
(
OBJECT
(
self
),
py__delitem__
,
Build
(
"(O)"
,
key
),
NULL
))
return
-
1
;
}
Py_XDECREF
(
v
);
return
0
;
}
static
PyMappingMethods
Wrapper_as_mapping
=
{
(
inquiry
)
Wrapper_length
,
/*mp_length*/
(
binaryfunc
)
Wrapper_subscript
,
/*mp_subscript*/
(
objobjargproc
)
Wrapper_ass_sub
,
/*mp_ass_subscript*/
};
/* -------------------------------------------------------------- */
/* Code to access Wrapper objects as numbers */
static
PyObject
*
Wrapper_sub
(
Wrapper
*
self
,
PyObject
*
o
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__sub__
,
Build
(
"(O)"
,
o
),
NULL
);
}
static
PyObject
*
Wrapper_div
(
Wrapper
*
self
,
PyObject
*
o
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__div__
,
Build
(
"(O)"
,
o
),
NULL
);
}
static
PyObject
*
Wrapper_mod
(
Wrapper
*
self
,
PyObject
*
o
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__mod__
,
Build
(
"(O)"
,
o
),
NULL
);
}
static
PyObject
*
Wrapper_divmod
(
Wrapper
*
self
,
PyObject
*
o
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__divmod__
,
Build
(
"(O)"
,
o
),
NULL
);
}
static
PyObject
*
Wrapper_pow
(
Wrapper
*
self
,
PyObject
*
o
,
PyObject
*
m
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__pow__
,
Build
(
"(OO)"
,
o
,
m
),
NULL
);
}
static
PyObject
*
Wrapper_neg
(
Wrapper
*
self
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__neg__
,
NULL
,
NULL
);
}
static
PyObject
*
Wrapper_pos
(
Wrapper
*
self
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__pos__
,
NULL
,
NULL
);
}
static
PyObject
*
Wrapper_abs
(
Wrapper
*
self
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__abs__
,
NULL
,
NULL
);
}
static
PyObject
*
Wrapper_invert
(
Wrapper
*
self
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__invert__
,
NULL
,
NULL
);
}
static
PyObject
*
Wrapper_lshift
(
Wrapper
*
self
,
PyObject
*
o
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__lshift__
,
Build
(
"(O)"
,
o
),
NULL
);
}
static
PyObject
*
Wrapper_rshift
(
Wrapper
*
self
,
PyObject
*
o
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__rshift__
,
Build
(
"(O)"
,
o
),
NULL
);
}
static
PyObject
*
Wrapper_and
(
Wrapper
*
self
,
PyObject
*
o
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__and__
,
Build
(
"(O)"
,
o
),
NULL
);
}
static
PyObject
*
Wrapper_xor
(
Wrapper
*
self
,
PyObject
*
o
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__xor__
,
Build
(
"(O)"
,
o
),
NULL
);
}
static
PyObject
*
Wrapper_or
(
Wrapper
*
self
,
PyObject
*
o
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__or__
,
Build
(
"(O)"
,
o
),
NULL
);
}
static
int
Wrapper_coerce
(
Wrapper
**
self
,
PyObject
**
o
)
{
PyObject
*
m
;
UNLESS
(
m
=
PyObject_GetAttr
(
OBJECT
(
*
self
),
py__coerce__
))
{
PyErr_Clear
();
Py_INCREF
(
*
self
);
Py_INCREF
(
*
o
);
return
0
;
}
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
*
o
));
UNLESS
(
m
)
return
-
1
;
UNLESS
(
PyArg_ParseTuple
(
m
,
"OO"
,
self
,
o
))
goto
err
;
Py_INCREF
(
*
self
);
Py_INCREF
(
*
o
);
Py_DECREF
(
m
);
return
0
;
err:
Py_DECREF
(
m
);
return
-
1
;
}
static
PyObject
*
Wrapper_int
(
Wrapper
*
self
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__int__
,
NULL
,
NULL
);
}
static
PyObject
*
Wrapper_long
(
Wrapper
*
self
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__long__
,
NULL
,
NULL
);
}
static
PyObject
*
Wrapper_float
(
Wrapper
*
self
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__float__
,
NULL
,
NULL
);
}
static
PyObject
*
Wrapper_oct
(
Wrapper
*
self
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__oct__
,
NULL
,
NULL
);
}
static
PyObject
*
Wrapper_hex
(
Wrapper
*
self
)
{
return
CallMethodO
(
OBJECT
(
self
),
py__hex__
,
NULL
,
NULL
);
}
static
PyNumberMethods
Wrapper_as_number
=
{
(
binaryfunc
)
Wrapper_add
,
/*nb_add*/
(
binaryfunc
)
Wrapper_sub
,
/*nb_subtract*/
(
binaryfunc
)
Wrapper_mul
,
/*nb_multiply*/
(
binaryfunc
)
Wrapper_div
,
/*nb_divide*/
(
binaryfunc
)
Wrapper_mod
,
/*nb_remainder*/
(
binaryfunc
)
Wrapper_divmod
,
/*nb_divmod*/
(
ternaryfunc
)
Wrapper_pow
,
/*nb_power*/
(
unaryfunc
)
Wrapper_neg
,
/*nb_negative*/
(
unaryfunc
)
Wrapper_pos
,
/*nb_positive*/
(
unaryfunc
)
Wrapper_abs
,
/*nb_absolute*/
(
inquiry
)
Wrapper_length
,
/*nb_nonzero*/
(
unaryfunc
)
Wrapper_invert
,
/*nb_invert*/
(
binaryfunc
)
Wrapper_lshift
,
/*nb_lshift*/
(
binaryfunc
)
Wrapper_rshift
,
/*nb_rshift*/
(
binaryfunc
)
Wrapper_and
,
/*nb_and*/
(
binaryfunc
)
Wrapper_xor
,
/*nb_xor*/
(
binaryfunc
)
Wrapper_or
,
/*nb_or*/
(
coercion
)
Wrapper_coerce
,
/*nb_coerce*/
(
unaryfunc
)
Wrapper_int
,
/*nb_int*/
(
unaryfunc
)
Wrapper_long
,
/*nb_long*/
(
unaryfunc
)
Wrapper_float
,
/*nb_float*/
(
unaryfunc
)
Wrapper_oct
,
/*nb_oct*/
(
unaryfunc
)
Wrapper_hex
,
/*nb_hex*/
};
/* -------------------------------------------------------- */
static
char
*
acquire_args
[]
=
{
"object"
,
"name"
,
"filter"
,
"extra"
,
"explicit"
,
"default"
,
"containment"
,
NULL
};
static
PyObject
*
Wrapper_acquire_method
(
Wrapper
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
PyObject
*
name
,
*
filter
=
0
,
*
extra
=
Py_None
;
PyObject
*
expl
=
0
,
*
defalt
=
0
;
int
explicit
=
1
;
int
containment
=
0
;
UNLESS
(
PyArg_ParseTupleAndKeywords
(
args
,
kw
,
"O|OOOOi"
,
acquire_args
+
1
,
&
name
,
&
filter
,
&
extra
,
&
explicit
,
&
defalt
,
&
containment
))
return
NULL
;
if
(
expl
)
explicit
=
PyObject_IsTrue
(
expl
);
if
(
filter
==
Py_None
)
filter
=
0
;
return
Wrapper_findattr
(
self
,
name
,
filter
,
extra
,
OBJECT
(
self
),
1
,
explicit
||
self
->
ob_type
==
(
PyTypeObject
*
)
&
Wrappertype
,
explicit
,
containment
);
}
static
PyObject
*
Wrapper_inContextOf
(
Wrapper
*
self
,
PyObject
*
args
)
{
PyObject
*
o
,
*
c
,
*
bc
;
int
inner
=
0
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O|i"
,
&
o
,
&
inner
))
return
NULL
;
if
(
inner
)
while
(
self
->
obj
&&
isWrapper
(
self
->
obj
))
self
=
WRAPPER
(
self
->
obj
);
c
=
OBJECT
(
self
);
while
(
1
)
{
if
(
c
==
o
)
return
PyInt_FromLong
(
1
);
if
(
c
&&
isWrapper
(
c
))
c
=
WRAPPER
(
c
)
->
container
;
else
break
;
}
/* Now try harder: Compare each object in the containment chain that
starts at self, with the object of the wrapper passed in to this
method. If a match is found, return 1. Thanks to Toby Dickenson.*/
while
(
isWrapper
(
o
)
&&
WRAPPER
(
o
)
->
obj
)
o
=
WRAPPER
(
o
)
->
obj
;
c
=
OBJECT
(
self
);
while
(
1
)
{
bc
=
c
;
while
(
isWrapper
(
bc
)
&&
WRAPPER
(
bc
)
->
obj
)
bc
=
WRAPPER
(
bc
)
->
obj
;
if
(
bc
==
o
)
return
PyInt_FromLong
(
1
);
if
(
c
&&
isWrapper
(
c
))
c
=
WRAPPER
(
c
)
->
container
;
else
break
;
}
return
PyInt_FromLong
(
0
);
}
static
struct
PyMethodDef
Wrapper_methods
[]
=
{
{
"__init__"
,
(
PyCFunction
)
Wrapper__init__
,
0
,
"Initialize an Acquirer Wrapper"
},
{
"acquire"
,
(
PyCFunction
)
Wrapper_acquire_method
,
METH_VARARGS
|
METH_KEYWORDS
,
"Get an attribute, acquiring it if necessary"
},
{
"aq_acquire"
,
(
PyCFunction
)
Wrapper_acquire_method
,
METH_VARARGS
|
METH_KEYWORDS
,
"Get an attribute, acquiring it if necessary"
},
{
"aq_inContextOf"
,
(
PyCFunction
)
Wrapper_inContextOf
,
METH_VARARGS
,
"Test whether the object is currently in the context of the argument"
},
{
NULL
,
NULL
}
/* sentinel */
};
static
PyExtensionClass
Wrappertype
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"ImplicitAcquirerWrapper"
,
/*tp_name*/
sizeof
(
Wrapper
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
Wrapper_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
0
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
Wrapper_compare
,
/*tp_compare*/
(
reprfunc
)
Wrapper_repr
,
/*tp_repr*/
&
Wrapper_as_number
,
/*tp_as_number*/
&
Wrapper_as_sequence
,
/*tp_as_sequence*/
&
Wrapper_as_mapping
,
/*tp_as_mapping*/
(
hashfunc
)
Wrapper_hash
,
/*tp_hash*/
(
ternaryfunc
)
Wrapper_call
,
/*tp_call*/
(
reprfunc
)
Wrapper_str
,
/*tp_str*/
(
getattrofunc
)
Wrapper_getattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
Wrapper_setattro
,
/*tp_setattr with object key*/
/* Space for future expansion */
0L
,
0L
,
"Wrapper object for implicit acquisition"
,
/* Documentation string */
METHOD_CHAIN
(
Wrapper_methods
),
EXTENSIONCLASS_BINDABLE_FLAG
,
};
static
PyExtensionClass
XaqWrappertype
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"ExplicitAcquirerWrapper"
,
/*tp_name*/
sizeof
(
Wrapper
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
Wrapper_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
0
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
Wrapper_compare
,
/*tp_compare*/
(
reprfunc
)
Wrapper_repr
,
/*tp_repr*/
0
,
/*tp_as_number*/
&
Wrapper_as_sequence
,
/*tp_as_sequence*/
&
Wrapper_as_mapping
,
/*tp_as_mapping*/
(
hashfunc
)
Wrapper_hash
,
/*tp_hash*/
(
ternaryfunc
)
Wrapper_call
,
/*tp_call*/
(
reprfunc
)
Wrapper_str
,
/*tp_str*/
(
getattrofunc
)
Xaq_getattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
Wrapper_setattro
,
/*tp_setattr with object key*/
/* Space for future expansion */
0L
,
0L
,
"Wrapper object for explicit acquisition"
,
/* Documentation string */
METHOD_CHAIN
(
Wrapper_methods
),
EXTENSIONCLASS_BINDABLE_FLAG
,
};
static
PyObject
*
acquire_of
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
inst
;
UNLESS
(
PyArg_ParseTuple
(
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
;
}
return
newWrapper
(
self
,
inst
,
(
PyTypeObject
*
)
&
Wrappertype
);
}
static
PyObject
*
xaq_of
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
inst
;
UNLESS
(
PyArg_ParseTuple
(
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
;
}
return
newWrapper
(
self
,
inst
,
(
PyTypeObject
*
)
&
XaqWrappertype
);
}
static
struct
PyMethodDef
Acquirer_methods
[]
=
{
{
"__of__"
,(
PyCFunction
)
acquire_of
,
METH_VARARGS
,
"__of__(context) -- return the object in a context"
},
{
NULL
,
NULL
}
/* sentinel */
};
static
struct
PyMethodDef
Xaq_methods
[]
=
{
{
"__of__"
,(
PyCFunction
)
xaq_of
,
METH_VARARGS
,
""
},
{
NULL
,
NULL
}
/* sentinel */
};
static
PyObject
*
module_aq_acquire
(
PyObject
*
ignored
,
PyObject
*
args
,
PyObject
*
kw
)
{
PyObject
*
self
;
PyObject
*
name
,
*
filter
=
0
,
*
extra
=
Py_None
;
PyObject
*
expl
=
0
,
*
defalt
=
0
;
int
explicit
=
1
,
containment
=
0
;
UNLESS
(
PyArg_ParseTupleAndKeywords
(
args
,
kw
,
"OO|OOOOi"
,
acquire_args
,
&
self
,
&
name
,
&
filter
,
&
extra
,
&
explicit
,
&
defalt
,
&
containment
))
return
NULL
;
if
(
expl
)
explicit
=
PyObject_IsTrue
(
expl
);
if
(
filter
==
Py_None
)
filter
=
0
;
/* We got a wrapped object, so business as usual */
if
(
isWrapper
(
self
))
return
Wrapper_findattr
(
WRAPPER
(
self
),
name
,
filter
,
extra
,
OBJECT
(
self
),
1
,
explicit
||
WRAPPER
(
self
)
->
ob_type
==
(
PyTypeObject
*
)
&
Wrappertype
,
explicit
,
containment
);
/* Not wrapped and no filter, so just getattr */
if
(
!
filter
)
return
PyObject_GetAttr
(
self
,
name
);
/* Crap, we've got to construct a wrapper so we can use Wrapper_findattr */
UNLESS
(
self
=
newWrapper
(
self
,
NULL
,
(
PyTypeObject
*
)
&
Wrappertype
))
return
NULL
;
ignored
=
Wrapper_findattr
(
WRAPPER
(
self
),
name
,
filter
,
extra
,
OBJECT
(
self
),
1
,
1
,
explicit
,
containment
);
/* get rid of temp wrapper */
Py_DECREF
(
self
);
return
ignored
;
}
static
PyObject
*
module_aq_get
(
PyObject
*
r
,
PyObject
*
args
)
{
PyObject
*
self
,
*
name
,
*
defalt
=
0
;
int
containment
=
0
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"OO|Oi"
,
&
self
,
&
name
,
&
defalt
,
&
containment
))
return
NULL
;
/* We got a wrapped object, so business as usual */
if
(
isWrapper
(
self
))
r
=
Wrapper_findattr
(
WRAPPER
(
self
),
name
,
0
,
0
,
OBJECT
(
self
),
1
,
1
,
1
,
containment
);
else
r
=
PyObject_GetAttr
(
self
,
name
);
if
(
!
r
&&
defalt
)
{
PyErr_Clear
();
r
=
defalt
;
Py_INCREF
(
r
);
}
return
r
;
}
static
PyObject
*
module_aq_base
(
PyObject
*
ignored
,
PyObject
*
args
)
{
PyObject
*
self
,
*
r
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
self
))
return
NULL
;
if
(
!
isWrapper
(
self
))
{
Py_INCREF
(
self
);
return
self
;
}
if
(
WRAPPER
(
self
)
->
obj
)
{
r
=
WRAPPER
(
self
)
->
obj
;
while
(
isWrapper
(
r
)
&&
WRAPPER
(
r
)
->
obj
)
r
=
WRAPPER
(
r
)
->
obj
;
}
else
r
=
Py_None
;
Py_INCREF
(
r
);
return
r
;
}
static
PyObject
*
module_aq_parent
(
PyObject
*
ignored
,
PyObject
*
args
)
{
PyObject
*
self
,
*
r
=
Py_None
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
self
))
return
NULL
;
if
(
isWrapper
(
self
)
&&
WRAPPER
(
self
)
->
container
)
r
=
WRAPPER
(
self
)
->
container
;
Py_INCREF
(
r
);
return
r
;
}
static
PyObject
*
module_aq_self
(
PyObject
*
ignored
,
PyObject
*
args
)
{
PyObject
*
self
,
*
r
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
self
))
return
NULL
;
if
(
!
isWrapper
(
self
))
{
Py_INCREF
(
self
);
return
self
;
}
if
(
WRAPPER
(
self
)
->
obj
)
r
=
WRAPPER
(
self
)
->
obj
;
else
r
=
Py_None
;
Py_INCREF
(
r
);
return
r
;
}
static
PyObject
*
module_aq_inner
(
PyObject
*
ignored
,
PyObject
*
args
)
{
PyObject
*
self
,
*
r
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
self
))
return
NULL
;
if
(
!
isWrapper
(
self
))
{
Py_INCREF
(
self
);
return
self
;
}
if
(
WRAPPER
(
self
)
->
obj
)
{
r
=
WRAPPER
(
self
)
->
obj
;
while
(
isWrapper
(
r
)
&&
WRAPPER
(
r
)
->
obj
)
{
self
=
r
;
r
=
WRAPPER
(
r
)
->
obj
;
}
r
=
self
;
}
else
r
=
Py_None
;
Py_INCREF
(
r
);
return
r
;
}
static
PyObject
*
module_aq_chain
(
PyObject
*
ignored
,
PyObject
*
args
)
{
PyObject
*
self
,
*
r
;
int
containment
=
0
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O|i"
,
&
self
,
&
containment
))
return
NULL
;
UNLESS
(
r
=
PyList_New
(
0
))
return
NULL
;
while
(
1
)
{
if
(
isWrapper
(
self
))
{
if
(
WRAPPER
(
self
)
->
obj
)
{
if
(
containment
)
while
(
WRAPPER
(
self
)
->
obj
&&
isWrapper
(
WRAPPER
(
self
)
->
obj
))
self
=
WRAPPER
(
self
)
->
obj
;
if
(
PyList_Append
(
r
,
OBJECT
(
self
))
<
0
)
goto
err
;
}
if
(
WRAPPER
(
self
)
->
container
)
{
self
=
WRAPPER
(
self
)
->
container
;
continue
;
}
}
else
if
(
PyList_Append
(
r
,
self
)
<
0
)
goto
err
;
break
;
}
return
r
;
err:
Py_DECREF
(
r
);
return
r
;
}
static
struct
PyMethodDef
methods
[]
=
{
{
"aq_acquire"
,
(
PyCFunction
)
module_aq_acquire
,
METH_VARARGS
|
METH_KEYWORDS
,
"aq_acquire(ob, name [, filter, extra, explicit]) -- "
"Get an attribute, acquiring it if necessary"
},
{
"aq_get"
,
(
PyCFunction
)
module_aq_get
,
METH_VARARGS
,
"aq_get(ob, name [, default]) -- "
"Get an attribute, acquiring it if necessary."
},
{
"aq_base"
,
(
PyCFunction
)
module_aq_base
,
METH_VARARGS
,
"aq_base(ob) -- Get the object unwrapped"
},
{
"aq_parent"
,
(
PyCFunction
)
module_aq_parent
,
METH_VARARGS
,
"aq_parent(ob) -- Get the parent of an object"
},
{
"aq_self"
,
(
PyCFunction
)
module_aq_self
,
METH_VARARGS
,
"aq_self(ob) -- Get the object with the outermost wrapper removed"
},
{
"aq_inner"
,
(
PyCFunction
)
module_aq_inner
,
METH_VARARGS
,
"aq_inner(ob) -- "
"Get the object with alll but the innermost wrapper removed"
},
{
"aq_chain"
,
(
PyCFunction
)
module_aq_chain
,
METH_VARARGS
,
"aq_chain(ob [, containment]) -- "
"Get a list of objects in the acquisition environment"
},
{
NULL
,
NULL
}
};
void
initAcquisition
()
{
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.47 $"
;
PURE_MIXIN_CLASS
(
Acquirer
,
"Base class for objects that implicitly"
" acquire attributes from containers
\n
"
,
Acquirer_methods
);
PURE_MIXIN_CLASS
(
ExplicitAcquirer
,
"Base class for objects that explicitly"
" acquire attributes from containers
\n
"
,
Xaq_methods
);
UNLESS
(
ExtensionClassImported
)
return
;
UNLESS
(
Acquired
=
PyString_FromStringAndSize
(
NULL
,
42
))
return
;
strcpy
(
PyString_AsString
(
Acquired
),
"<Special Object Used to Force Acquisition>"
);
/* Create the module and add the functions */
m
=
Py_InitModule4
(
"Acquisition"
,
methods
,
"Provide base classes for acquiring objects
\n\n
"
"$Id: Acquisition.c,v 1.47 2001/02/19 19:16:07 jeremy Exp $
\n
"
,
OBJECT
(
NULL
),
PYTHON_API_VERSION
);
d
=
PyModule_GetDict
(
m
);
init_py_names
();
PyExtensionClass_Export
(
d
,
"Acquirer"
,
AcquirerType
);
PyExtensionClass_Export
(
d
,
"ImplicitAcquisitionWrapper"
,
Wrappertype
);
PyExtensionClass_Export
(
d
,
"ExplicitAcquirer"
,
ExplicitAcquirerType
);
PyExtensionClass_Export
(
d
,
"ExplicitAcquisitionWrapper"
,
XaqWrappertype
);
/* Create aliases */
PyDict_SetItemString
(
d
,
"Implicit"
,
OBJECT
(
&
AcquirerType
));
PyDict_SetItemString
(
d
,
"Explicit"
,
OBJECT
(
&
ExplicitAcquirerType
));
PyDict_SetItemString
(
d
,
"__version__"
,
PyString_FromStringAndSize
(
rev
+
11
,
strlen
(
rev
+
11
)
-
2
));
PyDict_SetItemString
(
d
,
"Acquired"
,
Acquired
);
CHECK_FOR_ERRORS
(
"can't initialize module Acquisition"
);
}
lib/Components/ExtensionClass/ComputedAttribute.c
deleted
100644 → 0
View file @
7dbb8830
/*
Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
o Redistributions of source code must retain the above copyright
notice, this list of conditions, and the disclaimer that follows.
o Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
o Neither the name of Digital Creations nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
$Id: ComputedAttribute.c,v 1.4 2001/01/23 14:37:20 jim Exp $
If you have questions regarding this software,
contact:
Digital Creations L.C.
info@digicool.com
(540) 371-6909
*/
#include "ExtensionClass.h"
static
void
PyVar_Assign
(
PyObject
**
v
,
PyObject
*
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 OBJECT(O) ((PyObject*)(O))
typedef
struct
{
PyObject_HEAD
PyObject
*
callable
;
int
level
;
}
CA
;
static
PyObject
*
CA__init__
(
CA
*
self
,
PyObject
*
args
)
{
PyObject
*
callable
;
int
level
=
0
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O|i"
,
&
callable
,
&
level
))
return
NULL
;
if
(
level
>
0
)
{
callable
=
PyObject_CallFunction
(
OBJECT
(
self
->
ob_type
),
"Oi"
,
callable
,
self
->
level
-
1
);
UNLESS
(
callable
)
return
NULL
;
self
->
level
=
level
;
}
else
{
Py_INCREF
(
callable
);
self
->
level
=
0
;
}
self
->
callable
=
callable
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
void
CA_dealloc
(
CA
*
self
)
{
Py_DECREF
(
self
->
callable
);
Py_DECREF
(
self
->
ob_type
);
PyMem_DEL
(
self
);
}
static
PyObject
*
CA_of
(
CA
*
self
,
PyObject
*
args
)
{
if
(
self
->
level
>
0
)
{
Py_INCREF
(
self
->
callable
);
return
self
->
callable
;
}
if
(
PyString_Check
(
self
->
callable
))
{
/* Special case string as simple alias. */
PyObject
*
o
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
o
))
return
NULL
;
return
PyObject_GetAttr
(
o
,
self
->
callable
);
}
return
PyObject_CallObject
(
self
->
callable
,
args
);
}
static
struct
PyMethodDef
CA_methods
[]
=
{
{
"__init__"
,(
PyCFunction
)
CA__init__
,
METH_VARARGS
,
""
},
{
"__of__"
,
(
PyCFunction
)
CA_of
,
METH_VARARGS
,
""
},
{
NULL
,
NULL
}
/* sentinel */
};
static
PyExtensionClass
ComputedAttributeType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
"ComputedAttribute"
,
sizeof
(
CA
),
0
,
(
destructor
)
CA_dealloc
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
"ComputedAttribute(callable) -- Create a computed attribute"
,
METHOD_CHAIN
(
CA_methods
),
EXTENSIONCLASS_BINDABLE_FLAG
};
static
struct
PyMethodDef
methods
[]
=
{
{
NULL
,
NULL
}
};
void
initComputedAttribute
()
{
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.4 $"
;
UNLESS
(
ExtensionClassImported
)
return
;
ComputedAttributeType
.
tp_getattro
=
(
getattrofunc
)
PyExtensionClassCAPI
->
getattro
;
/* Create the module and add the functions */
m
=
Py_InitModule4
(
"ComputedAttribute"
,
methods
,
"Provide Computed Attributes
\n\n
"
"$Id: ComputedAttribute.c,v 1.4 2001/01/23 14:37:20 jim Exp $
\n
"
,
OBJECT
(
NULL
),
PYTHON_API_VERSION
);
d
=
PyModule_GetDict
(
m
);
PyExtensionClass_Export
(
d
,
"ComputedAttribute"
,
ComputedAttributeType
);
PyDict_SetItemString
(
d
,
"__version__"
,
PyString_FromStringAndSize
(
rev
+
11
,
strlen
(
rev
+
11
)
-
2
));
CHECK_FOR_ERRORS
(
"can't initialize module Acquisition"
);
}
lib/Components/ExtensionClass/ExtensionClass.c
deleted
100644 → 0
View file @
7dbb8830
/*
Copyright (c) 1996-2000, Digital Creations, Fredericksburg, VA, USA.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
o Redistributions of source code must retain the above copyright
notice, this list of conditions, and the disclaimer that follows.
o Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
o Neither the name of Digital Creations nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
$Id: ExtensionClass.c,v 1.44 2001/02/19 19:16:07 jeremy Exp $
If you have questions regarding this software,
contact:
Digital Creations L.C.
info@digicool.com
(540) 371-6909
*/
static
char
ExtensionClass_module_documentation
[]
=
"ExtensionClass - Classes implemented in c
\n
"
"
\n
"
"Built-in C classes are like Built-in types except that
\n
"
"they provide some of the behavior of Python classes:
\n
"
"
\n
"
" - They provide access to unbound methods,
\n
"
" - They can be called to create instances.
\n
"
"
\n
"
"$Id: ExtensionClass.c,v 1.44 2001/02/19 19:16:07 jeremy Exp $
\n
"
;
#include <stdio.h>
#include "ExtensionClass.h"
static
void
PyVar_Assign
(
PyObject
**
v
,
PyObject
*
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 OBJECT(O) ((PyObject*)O)
/* Declarations for objects of type ExtensionClass */
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))
#define HasMethodHook(O) \
((O)->ob_type->ob_type == (PyTypeObject*)&ECType && \
(((PyExtensionClass*)((O)->ob_type))->class_flags & \
EXTENSIONCLASS_METHODHOOK_FLAG))
#define ALLOC_FREE(T) \
if (free ## T) { \
self=free ## T; \
free ## T=(T*)self->self; \
self->ob_refcnt=1; \
} \
else UNLESS(self = PyObject_NEW(T, & T ## Type)) return NULL;
#define METH_BY_NAME (2 << 16)
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__of__
,
*
py__call__
,
*
py__call_method__
,
*
py__getitem__
,
*
py__setitem__
,
*
py__delitem__
,
*
py__getslice__
,
*
py__setslice__
,
*
py__delslice__
,
*
py__len__
,
*
py__getattr__
,
*
py__setattr__
,
*
py__delattr__
,
*
py__del__
,
*
py__repr__
,
*
py__str__
,
*
py__class__
,
*
py__name__
,
*
py__hash__
,
*
py__cmp__
,
*
py__var_size__
,
*
py__init__
,
*
py__getinitargs__
,
*
py__getstate__
,
*
py__setstate__
,
*
py__dict__
,
*
pyclass_
,
*
py__module__
;
static
PyObject
*
concat_fmt
=
0
;
static
PyObject
*
subclass_watcher
=
0
;
/* Object that subclass events */
static
void
init_py_names
()
{
#define INIT_PY_NAME(N) py ## N = PyString_FromString(#N)
INIT_PY_NAME
(
__add__
);
INIT_PY_NAME
(
__sub__
);
INIT_PY_NAME
(
__mul__
);
INIT_PY_NAME
(
__div__
);
INIT_PY_NAME
(
__mod__
);
INIT_PY_NAME
(
__pow__
);
INIT_PY_NAME
(
__divmod__
);
INIT_PY_NAME
(
__lshift__
);
INIT_PY_NAME
(
__rshift__
);
INIT_PY_NAME
(
__and__
);
INIT_PY_NAME
(
__or__
);
INIT_PY_NAME
(
__xor__
);
INIT_PY_NAME
(
__coerce__
);
INIT_PY_NAME
(
__neg__
);
INIT_PY_NAME
(
__pos__
);
INIT_PY_NAME
(
__abs__
);
INIT_PY_NAME
(
__nonzero__
);
INIT_PY_NAME
(
__inv__
);
INIT_PY_NAME
(
__int__
);
INIT_PY_NAME
(
__long__
);
INIT_PY_NAME
(
__float__
);
INIT_PY_NAME
(
__oct__
);
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
(
__len__
);
INIT_PY_NAME
(
__of__
);
INIT_PY_NAME
(
__call__
);
INIT_PY_NAME
(
__call_method__
);
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
(
__name__
);
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_
);
INIT_PY_NAME
(
__module__
);
#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
{
PyObject_HEAD
PyTypeObject
*
type
;
PyObject
*
self
;
char
*
name
;
PyCFunction
meth
;
int
flags
;
char
*
doc
;
}
CMethod
;
staticforward
PyTypeObject
CMethodType
;
#define CMethod_Check(O) ((O)->ob_type==&CMethodType)
#define UnboundCMethod_Check(O) \
((O)->ob_type==&CMethodType && ! ((CMethod*)(O))->self)
#define AsCMethod(O) ((CMethod*)(O))
#define CMETHOD(O) ((CMethod*)(O))
#define PMethod PyECMethodObject
#define PMethodType PyECMethodObjectType
staticforward
PyTypeObject
PMethodType
;
#define PMethod_Check(O) ((O)->ob_type==&PMethodType)
#define UnboundPMethod_Check(O) \
((O)->ob_type==&PMethodType && ! ((PMethod*)(O))->self)
#define UnboundEMethod_Check(O) \
(((O)->ob_type==&PMethodType ||(O)->ob_type==&CMethodType) \
&& ! ((PMethod*)(O))->self)
#define PMETHOD(O) ((PMethod*)(O))
static
PyObject
*
bindPMethod
(
PMethod
*
m
,
PyObject
*
inst
);
static
PyObject
*
#ifdef HAVE_STDARG_PROTOTYPES
/* VARARGS 2 */
JimErr_Format
(
PyObject
*
ErrType
,
char
*
stringformat
,
char
*
format
,
...)
#else
/* VARARGS */
JimErr_Format
(
va_alist
)
va_dcl
#endif
{
va_list
va
;
PyObject
*
args
=
0
,
*
retval
=
0
;
#ifdef HAVE_STDARG_PROTOTYPES
va_start
(
va
,
format
);
#else
PyObject
*
ErrType
;
char
*
stringformat
,
*
format
;
va_start
(
va
);
ErrType
=
va_arg
(
va
,
PyObject
*
);
stringformat
=
va_arg
(
va
,
char
*
);
format
=
va_arg
(
va
,
char
*
);
#endif
if
(
format
)
args
=
Py_VaBuildValue
(
format
,
va
);
va_end
(
va
);
if
(
format
&&
!
args
)
return
NULL
;
if
(
stringformat
&&
!
(
retval
=
PyString_FromString
(
stringformat
)))
return
NULL
;
if
(
retval
)
{
if
(
args
)
{
PyObject
*
v
;
v
=
PyString_Format
(
retval
,
args
);
Py_DECREF
(
retval
);
Py_DECREF
(
args
);
if
(
!
v
)
return
NULL
;
retval
=
v
;
}
}
else
if
(
args
)
retval
=
args
;
else
{
PyErr_SetObject
(
ErrType
,
Py_None
);
return
NULL
;
}
PyErr_SetObject
(
ErrType
,
retval
);
Py_DECREF
(
retval
);
return
NULL
;
}
static
PyObject
*
#ifdef HAVE_STDARG_PROTOTYPES
/* VARARGS 2 */
JimString_Build
(
char
*
out_format
,
char
*
build_format
,
...)
#else
/* VARARGS */
JimString_Build
(
va_alist
)
va_dcl
#endif
{
va_list
va
;
PyObject
*
args
,
*
retval
,
*
fmt
;
#ifdef HAVE_STDARG_PROTOTYPES
va_start
(
va
,
build_format
);
#else
char
*
build_format
;
char
*
out_format
;
va_start
(
va
);
out_format
=
va_arg
(
va
,
char
*
);
build_format
=
va_arg
(
va
,
char
*
);
#endif
if
(
build_format
)
args
=
Py_VaBuildValue
(
build_format
,
va
);
else
args
=
PyTuple_New
(
0
);
va_end
(
va
);
if
(
!
args
)
return
NULL
;
if
(
!
PyTuple_Check
(
args
))
{
PyObject
*
a
;
a
=
PyTuple_New
(
1
);
if
(
!
a
)
return
NULL
;
if
(
PyTuple_SetItem
(
a
,
0
,
args
)
==
-
1
)
return
NULL
;
args
=
a
;
}
fmt
=
PyString_FromString
(
out_format
);
retval
=
PyString_Format
(
fmt
,
args
);
Py_DECREF
(
args
);
Py_DECREF
(
fmt
);
return
retval
;
}
static
int
CMethod_issubclass
(
PyExtensionClass
*
sub
,
PyExtensionClass
*
type
)
{
int
i
,
l
;
PyObject
*
t
;
if
(
sub
==
type
)
return
1
;
if
(
!
sub
->
bases
)
return
0
;
l
=
PyTuple_Size
(
sub
->
bases
);
for
(
i
=
0
;
i
<
l
;
i
++
)
{
t
=
PyTuple_GET_ITEM
(
sub
->
bases
,
i
);
if
(
t
==
(
PyObject
*
)
type
)
return
1
;
if
(
ExtensionClass_Check
(
t
)
&&
AsExtensionClass
(
t
)
->
bases
&&
CMethod_issubclass
(
AsExtensionClass
(
t
),
type
)
)
return
1
;
}
return
0
;
}
#define Subclass_Check(C1,C2) \
CMethod_issubclass((PyExtensionClass *)(C1), (PyExtensionClass *)(C2))
#define SubclassInstance_Check(C1,C2) \
CMethod_issubclass((PyExtensionClass *)((C1)->ob_type), \
(PyExtensionClass *)(C2))
static
CMethod
*
freeCMethod
=
0
;
static
PyObject
*
newCMethod
(
PyExtensionClass
*
type
,
PyObject
*
inst
,
char
*
name
,
PyCFunction
meth
,
int
flags
,
char
*
doc
)
{
CMethod
*
self
;
ALLOC_FREE
(
CMethod
);
Py_INCREF
(
type
);
Py_XINCREF
(
inst
);
self
->
type
=
(
PyTypeObject
*
)
type
;
self
->
self
=
inst
;
self
->
name
=
name
;
self
->
meth
=
meth
;
self
->
flags
=
flags
;
self
->
doc
=
doc
;
return
(
PyObject
*
)
self
;
}
static
CMethod
*
bindCMethod
(
CMethod
*
m
,
PyObject
*
inst
)
{
CMethod
*
self
;
UNLESS
(
inst
->
ob_type
==
m
->
type
||
(
ExtensionInstance_Check
(
inst
)
&&
SubclassInstance_Check
(
inst
,
m
->
type
))
||
((
m
->
flags
&
METH_CLASS_METHOD
)
&&
ExtensionClass_Check
(
inst
))
)
{
Py_INCREF
(
m
);
return
m
;
}
ALLOC_FREE
(
CMethod
);
Py_INCREF
(
inst
);
Py_INCREF
(
m
->
type
);
self
->
type
=
m
->
type
;
self
->
self
=
inst
;
self
->
name
=
m
->
name
;
self
->
meth
=
m
->
meth
;
self
->
flags
=
m
->
flags
;
self
->
doc
=
m
->
doc
;
return
self
;
}
static
void
CMethod_dealloc
(
CMethod
*
self
)
{
#ifdef TRACE_DEALLOC
fprintf
(
stderr
,
"Deallocating C method %s
\n
"
,
self
->
name
);
#endif
Py_XDECREF
(
self
->
type
);
Py_XDECREF
(
self
->
self
);
self
->
self
=
(
PyObject
*
)
freeCMethod
;
freeCMethod
=
self
;
}
typedef
PyObject
*
(
*
call_by_name_type
)(
PyObject
*
,
PyObject
*
,
PyObject
*
,
PyTypeObject
*
);
typedef
PyObject
*
(
*
by_name_type
)(
PyObject
*
,
PyObject
*
,
PyTypeObject
*
);
static
PyObject
*
call_cmethod
(
CMethod
*
self
,
PyObject
*
inst
,
PyObject
*
args
,
PyObject
*
kw
)
{
if
(
!
(
self
->
flags
&
METH_VARARGS
))
{
int
size
=
PyTuple_Size
(
args
);
if
(
size
==
1
)
args
=
PyTuple_GET_ITEM
(
args
,
0
);
else
if
(
size
==
0
)
args
=
NULL
;
}
if
(
self
->
flags
&
METH_KEYWORDS
)
{
if
(
self
->
flags
&
METH_BY_NAME
)
return
(
*
(
call_by_name_type
)
self
->
meth
)(
inst
,
args
,
kw
,
self
->
type
);
else
return
(
*
(
PyCFunctionWithKeywords
)
self
->
meth
)(
inst
,
args
,
kw
);
}
else
if
(
self
->
flags
&
METH_BY_NAME
)
return
(
*
(
by_name_type
)
self
->
meth
)(
inst
,
args
,
self
->
type
);
else
{
if
(
kw
!=
NULL
&&
PyDict_Size
(
kw
)
!=
0
)
{
PyErr_SetString
(
PyExc_TypeError
,
"this function takes no keyword arguments"
);
return
NULL
;
}
return
(
*
self
->
meth
)(
inst
,
args
);
}
}
static
char
*
hook_mark
=
"C method being called through a hook."
;
static
PyObject
*
callCMethodWithHook
(
CMethod
*
self
,
PyObject
*
inst
,
PyObject
*
args
,
PyObject
*
kw
)
{
PyObject
*
hook
,
*
m
;
UNLESS
(
m
=
newCMethod
(
AsExtensionClass
(
self
->
type
),
inst
,
self
->
name
,
self
->
meth
,
self
->
flags
,
hook_mark
))
return
NULL
;
if
((
hook
=
PyObject_GetAttr
(
inst
,
py__call_method__
)))
{
if
((
CMethod_Check
(
hook
)
&&
CMETHOD
(
hook
)
->
meth
==
self
->
meth
)
||
(
PMethod_Check
(
hook
)
&&
CMethod_Check
(
PMETHOD
(
hook
)
->
meth
)
&&
CMETHOD
(
PMETHOD
(
hook
)
->
meth
)
->
meth
==
self
->
meth
)
)
{
/* Oops, we are already calling the hook! */
Py_DECREF
(
hook
);
return
PyEval_CallObjectWithKeywords
(
m
,
args
,
kw
);
}
if
(
kw
)
ASSIGN
(
hook
,
PyObject_CallFunction
(
hook
,
"OOO"
,
m
,
args
,
kw
));
else
ASSIGN
(
hook
,
PyObject_CallFunction
(
hook
,
"OO"
,
m
,
args
));
}
else
{
PyErr_Clear
();
hook
=
PyEval_CallObjectWithKeywords
(
m
,
args
,
kw
);
}
Py_DECREF
(
m
);
return
hook
;
}
static
PyObject
*
CMethod_call
(
CMethod
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
int
size
;
if
(
self
->
self
)
{
if
(
HasMethodHook
(
self
->
self
)
&&
self
->
doc
!=
hook_mark
/* This check prevents infinite recursion */
)
return
callCMethodWithHook
(
self
,
self
->
self
,
args
,
kw
);
return
call_cmethod
(
self
,
self
->
self
,
args
,
kw
);
}
if
((
size
=
PyTuple_Size
(
args
))
>
0
)
{
PyObject
*
first
=
0
;
UNLESS
(
first
=
PyTuple_GET_ITEM
(
args
,
0
))
return
NULL
;
if
(
first
->
ob_type
==
self
->
type
||
(
ExtensionInstance_Check
(
first
)
&&
CMethod_issubclass
(
ExtensionClassOf
(
first
),
AsExtensionClass
(
self
->
type
))
)
)
{
PyObject
*
rest
=
0
;
UNLESS
(
rest
=
PySequence_GetSlice
(
args
,
1
,
size
))
return
NULL
;
if
(
HasMethodHook
(
first
)
&&
self
->
doc
!=
hook_mark
/* This check prevents infinite recursion */
)
ASSIGN
(
rest
,
callCMethodWithHook
(
self
,
first
,
rest
,
kw
)
);
else
ASSIGN
(
rest
,
call_cmethod
(
self
,
first
,
rest
,
kw
)
);
return
rest
;
}
}
return
JimErr_Format
(
PyExc_TypeError
,
"unbound C method must be called with %s 1st argument"
,
"s"
,
self
->
type
->
tp_name
);
}
static
PyObject
*
CMethod_getattro
(
CMethod
*
self
,
PyObject
*
oname
)
{
PyObject
*
r
;
if
(
PyString_Check
(
oname
))
{
char
*
name
;
UNLESS
(
name
=
PyString_AsString
(
oname
))
return
NULL
;
if
(
name
[
0
]
!=
'_'
&&
name
[
0
]
&&
name
[
1
]
!=
'_'
&&
PyEval_GetRestricted
())
{
PyErr_SetString
(
PyExc_RuntimeError
,
"function attributes not accessible in restricted mode"
);
return
NULL
;
}
if
(
strcmp
(
name
,
"__name__"
)
==
0
||
strcmp
(
name
,
"func_name"
)
==
0
)
return
PyString_FromString
(
self
->
name
);
if
(
strcmp
(
name
,
"func_code"
)
==
0
||
strcmp
(
name
,
"im_func"
)
==
0
)
{
Py_INCREF
(
self
);
return
(
PyObject
*
)
self
;
}
if
(
strcmp
(
name
,
"__doc__"
)
==
0
||
strcmp
(
name
,
"func_doc"
)
==
0
)
{
if
(
self
->
doc
)
return
PyString_FromString
(
self
->
doc
);
else
return
PyString_FromString
(
""
);
}
if
(
strcmp
(
name
,
"im_class"
)
==
0
)
{
Py_INCREF
(
self
->
type
);
return
(
PyObject
*
)
self
->
type
;
}
if
(
strcmp
(
name
,
"im_self"
)
==
0
)
{
if
(
self
->
self
)
r
=
self
->
self
;
else
r
=
Py_None
;
Py_INCREF
(
r
);
return
r
;
}
}
if
(
self
->
self
)
/* Psuedo attributes */
{
UNLESS
(
oname
=
Py_BuildValue
(
"sO"
,
self
->
name
,
oname
))
return
NULL
;
UNLESS_ASSIGN
(
oname
,
PyString_Format
(
concat_fmt
,
oname
))
return
NULL
;
r
=
PyObject_GetAttr
(
OBJECT
(
self
->
self
),
py__class__
);
if
(
r
)
{
ASSIGN
(
r
,
PyObject_GetAttr
(
r
,
oname
));
if
(
r
)
{
if
(
UnboundCMethod_Check
(
r
))
ASSIGN
(
r
,
(
PyObject
*
)
bindCMethod
((
CMethod
*
)
r
,
self
->
self
));
else
if
(
UnboundPMethod_Check
(
r
))
ASSIGN
(
r
,
bindPMethod
((
PMethod
*
)
r
,
self
->
self
));
}
}
Py_DECREF
(
oname
);
return
r
;
}
PyErr_SetObject
(
PyExc_AttributeError
,
oname
);
return
NULL
;
}
static
int
CMethod_setattro
(
CMethod
*
self
,
PyObject
*
oname
,
PyObject
*
v
)
{
int
r
;
if
(
self
->
self
&&
!
PyEval_GetRestricted
())
/* Psuedo attributes */
{
UNLESS
(
oname
=
Py_BuildValue
(
"sO"
,
self
->
name
,
oname
))
return
-
1
;
UNLESS_ASSIGN
(
oname
,
PyString_Format
(
concat_fmt
,
oname
))
return
-
1
;
r
=
PyObject_SetAttr
(
self
->
self
,
oname
,
v
);
Py_DECREF
(
oname
);
return
r
;
}
PyErr_SetObject
(
PyExc_AttributeError
,
oname
);
return
-
1
;
}
static
PyTypeObject
CMethodType
=
{
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*/
0
,
/*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*/
(
getattrofunc
)
CMethod_getattro
,
/* tp_getattro */
(
setattrofunc
)
0
/*CMethod_setattro*/
,
/* tp_setattro */
/* Space for future expansion */
0L
,
0L
,
"Storage manager for unbound C function PyObject data"
/* Documentation string */
};
/* PMethod objects: */
static
PMethod
*
freePMethod
=
0
;
static
PyObject
*
newPMethod
(
PyExtensionClass
*
type
,
PyObject
*
meth
)
{
PMethod
*
self
;
ALLOC_FREE
(
PMethod
);
Py_INCREF
(
type
);
Py_INCREF
(
meth
);
self
->
type
=
(
PyTypeObject
*
)
type
;
self
->
self
=
NULL
;
self
->
meth
=
meth
;
return
(
PyObject
*
)
self
;
}
static
PyObject
*
bindPMethod
(
PMethod
*
m
,
PyObject
*
inst
)
{
PMethod
*
self
;
if
(
NeedsToBeBound
(
m
->
meth
))
return
CallMethodO
(
m
->
meth
,
py__of__
,
Build
(
"(O)"
,
inst
),
NULL
);
if
(
m
->
ob_refcnt
==
1
)
{
Py_INCREF
(
inst
);
ASSIGN
(
m
->
self
,
inst
);
Py_INCREF
(
m
);
return
(
PyObject
*
)
m
;
}
ALLOC_FREE
(
PMethod
);
Py_INCREF
(
inst
);
Py_INCREF
(
m
->
type
);
Py_INCREF
(
m
->
meth
);
self
->
type
=
m
->
type
;
self
->
self
=
inst
;
self
->
meth
=
m
->
meth
;
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
JimErr_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
)
{
#ifdef TRACE_DEALLOC
fprintf
(
stderr
,
"Deallocating PM ... "
);
#endif
Py_XDECREF
(
self
->
type
);
Py_XDECREF
(
self
->
self
);
Py_XDECREF
(
self
->
meth
);
self
->
self
=
(
PyObject
*
)
freePMethod
;
freePMethod
=
self
;
#ifdef TRACE_DEALLOC
fprintf
(
stderr
,
" Done Deallocating PM
\n
"
);
#endif
}
static
PyObject
*
callMethodWithPossibleHook
(
PyObject
*
inst
,
PyObject
*
meth
,
PyObject
*
args
,
PyObject
*
kw
)
{
if
(
HasMethodHook
(
inst
))
{
PyObject
*
hook
;
if
((
hook
=
PyObject_GetAttr
(
inst
,
py__call_method__
)))
{
if
(
PMethod_Check
(
hook
)
&&
((
PMethod
*
)
hook
)
->
meth
==
meth
)
{
/* Oops, we are already calling the hook! */
Py_DECREF
(
hook
);
return
PyEval_CallObjectWithKeywords
(
meth
,
args
,
kw
);
}
if
(
kw
)
ASSIGN
(
hook
,
PyObject_CallFunction
(
hook
,
"OOO"
,
meth
,
args
,
kw
));
else
ASSIGN
(
hook
,
PyObject_CallFunction
(
hook
,
"OO"
,
meth
,
args
));
return
hook
;
}
PyErr_Clear
();
}
return
PyEval_CallObjectWithKeywords
(
meth
,
args
,
kw
);
}
static
PyObject
*
call_PMethod
(
PMethod
*
self
,
PyObject
*
inst
,
PyObject
*
args
,
PyObject
*
kw
)
{
PyObject
*
a
;
if
(
CMethod_Check
(
self
->
meth
)
&&
CMETHOD
(
self
->
meth
)
->
type
->
tp_basicsize
==
sizeof
(
PyPureMixinObject
)
&&
!
(
CMETHOD
(
self
->
meth
)
->
self
)
)
{
/* Special HACK^H^H^Hcase:
we are wrapping an abstract unbound CMethod */
if
(
HasMethodHook
(
inst
)
&&
/* This check prevents infinite recursion: */
CMETHOD
(
self
->
meth
)
->
doc
!=
hook_mark
)
return
callCMethodWithHook
(
CMETHOD
(
self
->
meth
),
inst
,
args
,
kw
);
return
call_cmethod
(
CMETHOD
(
self
->
meth
),
inst
,
args
,
kw
);
}
else
{
a
=
Py_BuildValue
(
"(O)"
,
inst
);
if
(
a
)
ASSIGN
(
a
,
PySequence_Concat
(
a
,
args
));
if
(
a
)
ASSIGN
(
a
,
callMethodWithPossibleHook
(
inst
,
self
->
meth
,
a
,
kw
));
return
a
;
}
}
static
PyObject
*
PMethod_call
(
PMethod
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
int
size
;
if
(
self
->
self
)
return
call_PMethod
(
self
,
self
->
self
,
args
,
kw
);
if
((
size
=
PyTuple_Size
(
args
))
>
0
)
{
PyObject
*
first
=
0
,
*
ftype
=
0
;
UNLESS
(
first
=
PyTuple_GET_ITEM
(
args
,
0
))
return
NULL
;
if
(
!
self
->
type
||
((
ftype
=
PyObject_GetAttr
(
first
,
py__class__
))
&&
(
ftype
==
(
PyObject
*
)
self
->
type
||
(
ExtensionClass_Check
(
ftype
)
&&
CMethod_issubclass
(
AsExtensionClass
(
ftype
),
AsExtensionClass
(
self
->
type
))
)
)
)
)
{
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
,
callMethodWithPossibleHook
(
first
,
r
,
rest
,
kw
));
Py_DECREF
(
rest
);
return
r
;
}
Py_DECREF
(
ftype
);
return
callMethodWithPossibleHook
(
first
,
self
->
meth
,
args
,
kw
);
}
Py_XDECREF
(
ftype
);
}
return
JimErr_Format
(
PyExc_TypeError
,
"unbound Python method must be called with %s"
" 1st argument"
,
"s"
,
self
->
type
->
tp_name
);
}
static
PyObject
*
PMethod_getattro
(
PMethod
*
self
,
PyObject
*
oname
)
{
PyObject
*
r
;
if
(
PyString_Check
(
oname
))
{
char
*
name
;
UNLESS
(
name
=
PyString_AsString
(
oname
))
return
NULL
;
if
(
name
[
0
]
==
'_'
&&
name
[
1
]
==
'_'
)
{
if
(
strcmp
(
name
+
2
,
"name__"
)
==
0
)
return
PyObject_GetAttrString
(
self
->
meth
,
"__name__"
);
if
(
strcmp
(
name
+
2
,
"doc__"
)
==
0
)
return
PyObject_GetAttrString
(
self
->
meth
,
"__doc__"
);
}
else
if
(
PyEval_GetRestricted
())
{
PyErr_SetString
(
PyExc_RuntimeError
,
"function attributes not accessible in restricted mode"
);
return
NULL
;
}
else
if
(
name
[
0
]
==
'f'
&&
name
[
1
]
==
'u'
&&
name
[
2
]
==
'n'
&&
name
[
3
]
==
'c'
&&
name
[
4
]
==
'_'
)
{
if
(
strcmp
(
name
+
5
,
"name"
)
==
0
)
return
PyObject_GetAttrString
(
self
->
meth
,
"__name__"
);
if
(
strcmp
(
name
+
5
,
"doc"
)
==
0
)
return
PyObject_GetAttrString
(
self
->
meth
,
"__doc__"
);
}
if
(
*
name
++==
'i'
&&
*
name
++==
'm'
&&
*
name
++==
'_'
)
{
if
(
strcmp
(
name
,
"func"
)
==
0
)
{
Py_INCREF
(
self
->
meth
);
return
self
->
meth
;
}
if
(
strcmp
(
name
,
"class"
)
==
0
)
{
Py_INCREF
(
self
->
type
);
return
(
PyObject
*
)
self
->
type
;
}
if
(
strcmp
(
name
,
"self"
)
==
0
)
{
if
(
self
->
self
)
r
=
self
->
self
;
else
r
=
Py_None
;
Py_INCREF
(
r
);
return
r
;
}
}
}
if
(
self
->
meth
)
{
if
((
r
=
PyObject_GetAttr
(
self
->
meth
,
oname
)))
return
r
;
PyErr_Clear
();
if
(
self
->
self
)
/* Psuedo attrs */
{
PyObject
*
myname
;
UNLESS
(
myname
=
PyObject_GetAttr
(
self
->
meth
,
py__name__
))
return
NULL
;
oname
=
Py_BuildValue
(
"OO"
,
myname
,
oname
);
Py_DECREF
(
myname
);
UNLESS
(
oname
)
return
NULL
;
UNLESS_ASSIGN
(
oname
,
PyString_Format
(
concat_fmt
,
oname
))
return
NULL
;
r
=
PyObject_GetAttr
(
OBJECT
(
self
->
self
),
py__class__
);
if
(
r
)
{
ASSIGN
(
r
,
PyObject_GetAttr
(
r
,
oname
));
if
(
r
)
{
if
(
UnboundCMethod_Check
(
r
))
ASSIGN
(
r
,
(
PyObject
*
)
bindCMethod
((
CMethod
*
)
r
,
self
->
self
));
else
if
(
UnboundPMethod_Check
(
r
))
ASSIGN
(
r
,
bindPMethod
((
PMethod
*
)
r
,
self
->
self
));
}
}
Py_DECREF
(
oname
);
return
r
;
}
}
PyErr_SetObject
(
PyExc_AttributeError
,
oname
);
return
NULL
;
return
PyObject_GetAttr
(
self
->
meth
,
oname
);
}
static
int
PMethod_setattro
(
PMethod
*
self
,
PyObject
*
oname
,
PyObject
*
v
)
{
int
r
;
PyObject
*
spam
;
if
(
self
->
meth
)
{
if
((
spam
=
PyObject_GetAttr
(
self
->
meth
,
oname
)))
{
Py_DECREF
(
spam
);
PyErr_SetString
(
PyExc_TypeError
,
"Attempt to overwrite shared method attribute"
);
return
-
1
;
}
else
PyErr_Clear
();
if
(
self
->
self
&&
!
PyEval_GetRestricted
())
/* Psuedo attrs */
{
PyObject
*
myname
;
UNLESS
(
myname
=
PyObject_GetAttr
(
self
->
meth
,
py__name__
))
return
-
1
;
oname
=
Py_BuildValue
(
"OO"
,
myname
,
oname
);
Py_DECREF
(
myname
);
UNLESS
(
oname
)
return
-
1
;
UNLESS_ASSIGN
(
oname
,
PyString_Format
(
concat_fmt
,
oname
))
return
-
1
;
r
=
PyObject_SetAttr
(
self
->
self
,
oname
,
v
);
Py_DECREF
(
oname
);
return
r
;
}
}
PyErr_SetObject
(
PyExc_AttributeError
,
oname
);
return
-
1
;
}
static
PyTypeObject
PMethodType
=
{
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*/
0
,
/*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*/
(
getattrofunc
)
PMethod_getattro
,
/*tp_getattro*/
(
setattrofunc
)
0
/*PMethod_setattro*/
,
/* tp_setattro */
/* Space for future expansion */
0L
,
0L
,
"Storage manager for unbound C function PyObject data"
/* Documentation string */
};
static
PyObject
*
CCL_getattr
(
PyExtensionClass
*
,
PyObject
*
,
int
);
static
int
CCL_hasattr
(
PyExtensionClass
*
self
,
PyObject
*
name
)
{
PyObject
*
r
;
r
=
CCL_getattr
(
self
,
name
,
0
);
if
(
r
)
{
Py_DECREF
(
r
);
return
1
;
}
else
PyErr_Clear
();
return
0
;
}
/* Special Methods */
#define UNARY_OP(OP) \
static PyObject * \
OP ## _by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type) { \
UNLESS(PyArg_ParseTuple(args,"")) return NULL; \
return ob_type->tp_ ## OP(self); \
}
UNARY_OP
(
repr
)
UNARY_OP
(
str
)
static
PyObject
*
hash_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
long
r
;
UNLESS
(
PyArg_ParseTuple
(
args
,
""
))
return
NULL
;
UNLESS
(
-
1
!=
(
r
=
ob_type
->
tp_hash
(
self
)))
return
NULL
;
return
PyInt_FromLong
(
r
);
}
static
PyObject
*
call_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyObject
*
kw
,
PyTypeObject
*
ob_type
)
{
return
ob_type
->
tp_call
(
self
,
args
,
kw
);
}
static
PyObject
*
compare_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
PyObject
*
other
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
other
))
return
NULL
;
return
PyInt_FromLong
(
ob_type
->
tp_compare
(
self
,
other
));
}
static
PyObject
*
getattr_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
char
*
name
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"s"
,
&
name
))
return
NULL
;
return
ob_type
->
tp_getattr
(
self
,
name
);
}
static
PyObject
*
setattr_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
char
*
name
;
PyObject
*
v
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"sO"
,
&
name
,
&
v
))
return
NULL
;
UNLESS
(
-
1
!=
ob_type
->
tp_setattr
(
self
,
name
,
v
))
return
NULL
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyObject
*
delsetattr_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
char
*
name
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"s"
,
&
name
))
return
NULL
;
UNLESS
(
-
1
!=
ob_type
->
tp_setattr
(
self
,
name
,
NULL
))
return
NULL
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyObject
*
getattro_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
PyObject
*
name
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
name
))
return
NULL
;
return
ob_type
->
tp_getattro
(
self
,
name
);
}
static
PyObject
*
setattro_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
PyObject
*
name
;
PyObject
*
v
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"OO"
,
&
name
,
&
v
))
return
NULL
;
UNLESS
(
-
1
!=
ob_type
->
tp_setattro
(
self
,
name
,
v
))
return
NULL
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyObject
*
delsetattro_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
PyObject
*
name
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
name
))
return
NULL
;
UNLESS
(
-
1
!=
ob_type
->
tp_setattro
(
self
,
name
,
NULL
))
return
NULL
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyObject
*
length_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
long
r
;
UNLESS
(
PyArg_ParseTuple
(
args
,
""
))
return
NULL
;
if
(
ob_type
->
tp_as_sequence
)
{
UNLESS
(
-
1
!=
(
r
=
ob_type
->
tp_as_sequence
->
sq_length
(
self
)))
return
NULL
;
}
else
{
UNLESS
(
-
1
!=
(
r
=
ob_type
->
tp_as_mapping
->
mp_length
(
self
)))
return
NULL
;
}
return
PyInt_FromLong
(
r
);
}
static
PyObject
*
getitem_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
PyObject
*
key
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
key
))
return
NULL
;
if
(
ob_type
->
tp_as_mapping
)
return
ob_type
->
tp_as_mapping
->
mp_subscript
(
self
,
key
);
else
{
int
index
;
UNLESS
(
-
1
!=
(
index
=
PyInt_AsLong
(
key
)))
return
NULL
;
return
ob_type
->
tp_as_sequence
->
sq_item
(
self
,
index
);
}
}
static
PyCFunction
item_by_name
=
(
PyCFunction
)
getitem_by_name
;
static
PyCFunction
subscript_by_name
=
(
PyCFunction
)
getitem_by_name
;
static
PyObject
*
setitem_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
PyObject
*
key
,
*
v
;
long
r
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"OO"
,
&
key
,
&
v
))
return
NULL
;
if
(
ob_type
->
tp_as_mapping
)
r
=
ob_type
->
tp_as_mapping
->
mp_ass_subscript
(
self
,
key
,
v
);
else
{
int
index
;
UNLESS
(
-
1
!=
(
index
=
PyInt_AsLong
(
key
)))
return
NULL
;
r
=
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
;
static
PyCFunction
ass_subscript_by_name
=
(
PyCFunction
)
setitem_by_name
;
static
PyObject
*
slice_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
int
i1
,
i2
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"ii"
,
&
i1
,
&
i2
))
return
NULL
;
return
ob_type
->
tp_as_sequence
->
sq_slice
(
self
,
i1
,
i2
);
}
static
PyObject
*
ass_slice_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
int
i1
,
i2
;
PyObject
*
v
;
long
r
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"iiO"
,
&
i1
,
&
i2
,
&
v
))
return
NULL
;
r
=
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
*
concat_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
PyObject
*
other
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
other
))
return
NULL
;
return
ob_type
->
tp_as_sequence
->
sq_concat
(
self
,
other
);
}
static
PyObject
*
repeat_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
int
r
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"i"
,
&
r
))
return
NULL
;
return
ob_type
->
tp_as_sequence
->
sq_repeat
(
self
,
r
);
}
#define BINOP(OP,AOP) \
static PyObject * \
OP ## _by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type) { \
PyObject *v; \
UNLESS(PyArg_ParseTuple(args,"O",&v)) return NULL; \
return ob_type->tp_as_number->nb_ ## OP(self, v); \
}
BINOP
(
add
,
Add
)
BINOP
(
subtract
,
Subtract
)
BINOP
(
multiply
,
Multiply
)
BINOP
(
divide
,
Divide
)
BINOP
(
remainder
,
Remainder
)
BINOP
(
divmod
,
Divmod
)
static
PyObject
*
power_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
PyObject
*
v
,
*
z
=
NULL
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O|O"
,
&
v
,
&
z
))
return
NULL
;
return
ob_type
->
tp_as_number
->
nb_power
(
self
,
v
,
z
);
}
#define UNOP(OP) \
static PyObject * \
OP ## _by_name(PyObject *self, PyObject *args, PyTypeObject *ob_type) { \
UNLESS(PyArg_ParseTuple(args,"")) return NULL; \
return ob_type->tp_as_number->nb_ ## OP(self); \
}
UNOP
(
negative
)
UNOP
(
positive
)
UNOP
(
absolute
)
static
PyObject
*
nonzero_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
long
r
;
UNLESS
(
PyArg_ParseTuple
(
args
,
""
))
return
NULL
;
UNLESS
(
-
1
!=
(
r
=
ob_type
->
tp_as_number
->
nb_nonzero
(
self
)))
return
NULL
;
return
PyInt_FromLong
(
r
);
}
UNOP
(
invert
)
BINOP
(
lshift
,
Lshift
)
BINOP
(
rshift
,
Rshift
)
BINOP
(
and
,
And
)
BINOP
(
or
,
Or
)
BINOP
(
xor
,
Xor
)
static
PyObject
*
coerce_by_name
(
PyObject
*
self
,
PyObject
*
args
,
PyTypeObject
*
ob_type
)
{
PyObject
*
v
;
int
r
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
v
))
return
NULL
;
UNLESS
(
-
1
!=
(
r
=
ob_type
->
tp_as_number
->
nb_coerce
(
&
self
,
&
v
)))
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
args
=
Py_BuildValue
(
"OO"
,
self
,
v
);
Py_DECREF
(
self
);
Py_DECREF
(
v
);
return
args
;
}
UNOP
(
long
)
UNOP
(
int
)
UNOP
(
float
)
UNOP
(
oct
)
UNOP
(
hex
)
#define FILLENTRY(T,MN,N,F,D) if (T ## _ ## MN) { \
UNLESS(-1 != PyMapping_SetItemString(dict,"__" # N "__", \
newCMethod(type, NULL, "__" # N "__", \
(PyCFunction)MN ## _by_name, F | METH_BY_NAME, # D))) \
goto err; }
#define delFILLENTRY(T,MN,N,F,D) if (T ## _ ## MN) { \
UNLESS(-1 != PyMapping_SetItemString(dict,"__" # N "__", \
newCMethod(type, NULL, "__" # N "__", \
(PyCFunction)del ## MN ## _by_name, F | METH_BY_NAME, # D))) \
goto err; }
static
PyObject
*
getBaseDictionary
(
PyExtensionClass
*
type
)
{
PyNumberMethods
*
nm
;
PySequenceMethods
*
sm
;
PyMappingMethods
*
mm
;
PyObject
*
dict
;
UNLESS
(
dict
=
type
->
class_dictionary
)
UNLESS
(
dict
=
PyDict_New
())
return
NULL
;
FILLENTRY
(
type
->
tp
,
repr
,
repr
,
METH_VARARGS
,
"convert to an expression string"
);
FILLENTRY
(
type
->
tp
,
hash
,
hash
,
METH_VARARGS
,
"compute a hash value"
);
FILLENTRY
(
type
->
tp
,
call
,
call
,
METH_VARARGS
|
METH_KEYWORDS
,
"call as a function"
);
FILLENTRY
(
type
->
tp
,
compare
,
comp
,
METH_VARARGS
,
"compare with another object"
);
UNLESS
(
type
->
class_flags
&
EXTENSIONCLASS_PYTHONICATTR_FLAG
)
{
FILLENTRY
(
type
->
tp
,
getattr
,
getattr
,
METH_VARARGS
,
"Get an attribute"
);
FILLENTRY
(
type
->
tp
,
setattr
,
setattr
,
METH_VARARGS
,
"Set an attribute"
);
delFILLENTRY
(
type
->
tp
,
setattr
,
delattr
,
METH_VARARGS
,
"Delete an attribute"
);
FILLENTRY
(
type
->
tp
,
getattro
,
getattr
,
METH_VARARGS
,
"Get an attribute"
);
FILLENTRY
(
type
->
tp
,
setattro
,
setattr
,
METH_VARARGS
,
"Set an attribute"
);
delFILLENTRY
(
type
->
tp
,
setattro
,
delattr
,
METH_VARARGS
,
"Delete an attribute"
);
}
if
((
sm
=
type
->
tp_as_sequence
))
{
FILLENTRY
(
sm
->
sq
,
length
,
len
,
METH_VARARGS
,
"Get the object length"
);
FILLENTRY
(
sm
->
sq
,
repeat
,
mul
,
METH_VARARGS
,
"Get a new object that is the object repeated."
);
FILLENTRY
(
sm
->
sq
,
item
,
getitem
,
METH_VARARGS
,
"Get an item"
);
FILLENTRY
(
sm
->
sq
,
slice
,
getslice
,
METH_VARARGS
,
"Get a slice"
);
FILLENTRY
(
sm
->
sq
,
ass_item
,
setitem
,
METH_VARARGS
,
"Assign an item"
);
FILLENTRY
(
sm
->
sq
,
ass_slice
,
setslice
,
METH_VARARGS
,
"Assign a slice"
);
}
if
((
mm
=
type
->
tp_as_mapping
))
{
FILLENTRY
(
mm
->
mp
,
length
,
len
,
METH_VARARGS
,
"Get the object length"
);
FILLENTRY
(
mm
->
mp
,
subscript
,
getitem
,
METH_VARARGS
,
"Get an item"
);
FILLENTRY
(
mm
->
mp
,
ass_subscript
,
setitem
,
METH_VARARGS
,
"Assign an item"
);
}
if
((
nm
=
type
->
tp_as_number
)
!=
NULL
)
{
FILLENTRY
(
nm
->
nb
,
add
,
add
,
METH_VARARGS
,
"Add to another"
);
FILLENTRY
(
nm
->
nb
,
subtract
,
sub
,
METH_VARARGS
,
"Subtract another"
);
FILLENTRY
(
nm
->
nb
,
multiply
,
mul
,
METH_VARARGS
,
"Multiple by another"
);
FILLENTRY
(
nm
->
nb
,
divide
,
div
,
METH_VARARGS
,
"Divide by another"
);
FILLENTRY
(
nm
->
nb
,
remainder
,
mod
,
METH_VARARGS
,
"Compute a remainder"
);
FILLENTRY
(
nm
->
nb
,
power
,
pow
,
METH_VARARGS
,
"Raise to a power"
);
FILLENTRY
(
nm
->
nb
,
divmod
,
divmod
,
METH_VARARGS
,
"Compute the whole result and remainder of dividing
\n
"
"by another"
);
FILLENTRY
(
nm
->
nb
,
negative
,
neg
,
METH_VARARGS
,
"Get the negative value."
);
FILLENTRY
(
nm
->
nb
,
positive
,
pos
,
METH_VARARGS
,
"Compute positive value"
);
FILLENTRY
(
nm
->
nb
,
absolute
,
abs
,
METH_VARARGS
,
"Compute absolute value"
);
FILLENTRY
(
nm
->
nb
,
nonzero
,
nonzero
,
METH_VARARGS
,
"Determine whether nonzero"
);
FILLENTRY
(
nm
->
nb
,
invert
,
inv
,
METH_VARARGS
,
"Compute inverse"
);
FILLENTRY
(
nm
->
nb
,
lshift
,
lshift
,
METH_VARARGS
,
"Shist left"
);
FILLENTRY
(
nm
->
nb
,
rshift
,
rshift
,
METH_VARARGS
,
"Shist right"
);
FILLENTRY
(
nm
->
nb
,
and
,
and
,
METH_VARARGS
,
"bitwize logical and"
);
FILLENTRY
(
nm
->
nb
,
or
,
or
,
METH_VARARGS
,
"bitwize logical or"
);
FILLENTRY
(
nm
->
nb
,
xor
,
xor
,
METH_VARARGS
,
"bitwize logical excusive or"
);
FILLENTRY
(
nm
->
nb
,
coerce
,
coerce
,
METH_VARARGS
,
"Coerce woth another to a common type"
);
FILLENTRY
(
nm
->
nb
,
int
,
int
,
METH_VARARGS
,
"Convert to an integer"
);
FILLENTRY
(
nm
->
nb
,
long
,
long
,
METH_VARARGS
,
"Convert to an infinite-precision integer"
);
FILLENTRY
(
nm
->
nb
,
float
,
float
,
METH_VARARGS
,
"Convert to floating point number"
);
FILLENTRY
(
nm
->
nb
,
oct
,
oct
,
METH_VARARGS
,
"Convert to an octal string"
);
FILLENTRY
(
nm
->
nb
,
hex
,
hex
,
METH_VARARGS
,
"Convert to a hexadecimal string"
);
}
if
((
sm
=
type
->
tp_as_sequence
))
{
FILLENTRY
(
sm
->
sq
,
concat
,
add
,
METH_VARARGS
,
"Concatinate the object with another"
);
}
return
dict
;
err:
Py_DECREF
(
dict
);
return
NULL
;
}
#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
();
if
(
ExtensionClassOf
(
self
)
->
class_flags
&
EXTENSIONCLASS_BASICNEW_FLAG
)
{
args
=
Py_None
;
Py_INCREF
(
args
);
}
else
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
*
args
)
{
PyObject
*
name
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O!"
,
&
PyString_Type
,
&
name
))
return
NULL
;
return
CCL_getattr
(
AsExtensionClass
(
self
),
name
,
1
);
}
static
PyObject
*
basicnew
(
PyExtensionClass
*
self
,
PyObject
*
args
)
{
PyObject
*
inst
=
0
;
typedef
struct
{
PyObject_VAR_HEAD
}
PyVarObject__
;
if
(
!
self
->
tp_dealloc
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Attempt to create instance of an abstract type"
);
return
NULL
;
}
UNLESS
(
self
->
class_flags
&
EXTENSIONCLASS_BASICNEW_FLAG
)
return
PyObject_CallObject
(
OBJECT
(
self
),
NULL
);
if
(
self
->
tp_itemsize
)
{
/* We have a variable-sized object, we need to get it's size */
PyObject
*
var_size
;
int
size
;
UNLESS
(
var_size
=
CCL_getattr
(
self
,
py__var_size__
,
0
))
return
NULL
;
UNLESS_ASSIGN
(
var_size
,
PyObject_CallObject
(
var_size
,
NULL
))
return
NULL
;
size
=
PyInt_AsLong
(
var_size
);
if
(
PyErr_Occurred
())
return
NULL
;
UNLESS
(
inst
=
PyObject_NEW_VAR
(
PyObject
,(
PyTypeObject
*
)
self
,
size
))
return
NULL
;
memset
(
inst
,
0
,
self
->
tp_basicsize
+
self
->
tp_itemsize
*
size
);
((
PyVarObject__
*
)
inst
)
->
ob_size
=
size
;
}
else
{
UNLESS
(
inst
=
PyObject_NEW
(
PyObject
,(
PyTypeObject
*
)
self
))
return
NULL
;
memset
(
inst
,
0
,
self
->
tp_basicsize
);
}
inst
->
ob_refcnt
=
1
;
inst
->
ob_type
=
(
PyTypeObject
*
)
self
;
Py_INCREF
(
self
);
if
(
ClassHasInstDict
(
self
))
UNLESS
(
INSTANCE_DICT
(
inst
)
=
PyDict_New
())
goto
err
;
if
(
self
->
bases
&&
subclass_watcher
&&
!
PyObject_CallMethod
(
subclass_watcher
,
"created"
,
"O"
,
inst
))
PyErr_Clear
();
return
inst
;
err:
Py_DECREF
(
inst
);
return
NULL
;
}
struct
PyMethodDef
ECI_methods
[]
=
{
{
"__reduce__"
,(
PyCFunction
)
EC_reduce
,
METH_VARARGS
,
"__reduce__() -- Reduce an instance into it's class and creation data"
},
{
"inheritedAttribute"
,(
PyCFunction
)
inheritedAttribute
,
METH_VARARGS
|
METH_CLASS_METHOD
,
"inheritedAttribute(class,name) -- Get an inherited attribute
\n\n
"
"Get an attribute that would be inherited if the given (extension)
\n
"
"class did not define it. This method is used when overriding
\n
"
"inherited methods. It provides 2 advantages over accessing
\n
"
"
\n
"
"attributes directly through a superclass:
\n
"
"
\n
"
"1. The superclass need not be known,
\n
"
"
\n
"
"2. The superclass may be a Python class. Without this method, it would
\n
"
" be possible to override methods inherited from python classes because
\n
"
" unbound methods gotten from Python classes cannot be called with
\n
"
" extension class instances.
\n
"
},
{
"__basicnew__"
,(
PyCFunction
)
basicnew
,
METH_VARARGS
|
METH_CLASS_METHOD
,
"__basicnew__() -- return a new uninitialized instance"
},
{
NULL
,
NULL
}
/* sentinel */
};
static
PyObject
*
initializeBaseExtensionClass
(
PyExtensionClass
*
self
)
{
static
PyMethodChain
top
=
{
ECI_methods
,
NULL
};
PyMethodChain
*
chain
;
PyObject
*
dict
;
int
abstract
;
/* Is this an abstract, or at least a dataless, class? */
abstract
=
self
->
tp_basicsize
==
sizeof
(
PyPureMixinObject
);
self
->
ob_type
=
(
PyTypeObject
*
)
&
ECType
;
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
;
if
(
&
self
->
methods
)
chain
=&
(
self
->
methods
);
else
chain
=&
top
;
while
(
1
)
{
PyMethodDef
*
ml
=
chain
->
methods
;
for
(;
ml
&&
ml
->
ml_name
!=
NULL
;
ml
++
)
{
if
(
ml
->
ml_meth
)
{
if
(
!
PyMapping_HasKeyString
(
dict
,
ml
->
ml_name
))
{
PyObject
*
m
;
/* Note that we create a circular reference here.
I suppose that this isn't so bad, since this is
probably a static thing anyway. Still, it is a
bit troubling. Oh well.
*/
if
(
ml
->
ml_flags
&
METH_CLASS_METHOD
)
{
UNLESS
(
m
=
newCMethod
(
AsExtensionClass
(
self
->
ob_type
),
NULL
,
ml
->
ml_name
,
ml
->
ml_meth
,
ml
->
ml_flags
,
ml
->
ml_doc
))
return
NULL
;
}
else
{
UNLESS
(
m
=
newCMethod
(
self
,
NULL
,
ml
->
ml_name
,
ml
->
ml_meth
,
ml
->
ml_flags
,
ml
->
ml_doc
))
return
NULL
;
if
(
abstract
)
UNLESS_ASSIGN
(
m
,
newPMethod
(
self
,
m
))
return
NULL
;
}
if
(
PyMapping_SetItemString
(
dict
,
ml
->
ml_name
,
m
)
<
0
)
return
NULL
;
}
}
else
if
(
ml
->
ml_doc
&&
*
(
ml
->
ml_doc
))
{
/* No actual meth, this is probably to hook a doc string
onto a special method. */
PyObject
*
m
;
if
((
m
=
PyMapping_GetItemString
(
dict
,
ml
->
ml_name
)))
{
if
(
m
->
ob_type
==&
CMethodType
)
((
CMethod
*
)(
m
))
->
doc
=
ml
->
ml_doc
;
}
else
PyErr_Clear
();
}
}
if
(
chain
==
&
top
)
break
;
UNLESS
(
chain
=
chain
->
link
)
chain
=&
top
;
}
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
);
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
);
}
if
(((
PyExtensionClass
*
)
self
->
ob_type
)
!=
self
)
{
Py_XDECREF
(
self
->
ob_type
);
}
PyMem_DEL
(
self
);
}
static
PyObject
*
ExtensionClass_FindInstanceAttribute
(
PyObject
*
inst
,
PyObject
*
oname
,
char
*
name
)
{
/* Look up an attribute for an instance from:
The instance dictionary,
The class dictionary, or
The base objects.
*/
PyObject
*
r
=
0
;
PyExtensionClass
*
self
;
if
(
!
name
)
return
NULL
;
self
=
(
PyExtensionClass
*
)(
inst
->
ob_type
);
if
(
*
name
==
'_'
&&
name
[
1
]
==
'_'
)
{
char
*
n
=
name
+
2
;
if
(
*
n
==
'c'
&&
strcmp
(
n
,
"class__"
)
==
0
)
{
Py_INCREF
(
self
);
return
(
PyObject
*
)
self
;
}
if
(
ClassHasInstDict
(
self
)
&&
*
n
==
'd'
&&
strcmp
(
n
,
"dict__"
)
==
0
)
{
r
=
INSTANCE_DICT
(
inst
);
Py_INCREF
(
r
);
return
r
;
}
}
if
(
ClassHasInstDict
(
self
))
{
r
=
INSTANCE_DICT
(
inst
);
if
((
r
=
PyObject_GetItem
(
r
,
oname
))
&&
NeedsToBeBound
(
r
))
{
ASSIGN
(
r
,
CallMethodO
(
r
,
py__of__
,
Build
(
"(O)"
,
inst
),
NULL
));
UNLESS
(
r
)
return
NULL
;
}
}
UNLESS
(
r
)
{
if
(
*
name
==
'_'
&&
name
[
1
]
==
'_'
&&
(
(
name
[
2
]
==
'b'
&&
strcmp
(
name
+
2
,
"bases__"
)
==
0
)
||
(
name
[
2
]
==
'd'
&&
strcmp
(
name
+
2
,
"dict__"
)
==
0
)
)
)
{
PyErr_SetObject
(
PyExc_AttributeError
,
oname
);
return
NULL
;
}
PyErr_Clear
();
UNLESS
(
r
=
CCL_getattr
(
self
,
oname
,
0
))
return
NULL
;
/* We got something from our class, maybe its an unbound method. */
if
(
UnboundCMethod_Check
(
r
))
ASSIGN
(
r
,(
PyObject
*
)
bindCMethod
((
CMethod
*
)
r
,
inst
));
else
if
(
UnboundPMethod_Check
(
r
))
ASSIGN
(
r
,
bindPMethod
((
PMethod
*
)
r
,
inst
));
}
return
r
;
}
static
PyObject
*
EC_findiattrs
(
PyObject
*
self
,
char
*
name
)
{
PyObject
*
s
,
*
r
;
UNLESS
(
s
=
PyString_FromString
(
name
))
return
NULL
;
r
=
ExtensionClass_FindInstanceAttribute
(
self
,
s
,
name
);
Py_DECREF
(
s
);
return
r
;
}
static
PyObject
*
EC_findiattro
(
PyObject
*
self
,
PyObject
*
name
)
{
return
ExtensionClass_FindInstanceAttribute
(
self
,
name
,
PyString_AsString
(
name
));
}
static
int
subclass_simple_setattr
(
PyObject
*
self
,
char
*
name
,
PyObject
*
v
);
static
PyObject
*
CCL_getattr
(
PyExtensionClass
*
self
,
PyObject
*
oname
,
int
look_super
)
{
PyObject
*
r
=
0
;
if
(
!
look_super
)
r
=
PyObject_GetItem
(
self
->
class_dictionary
,
oname
);
UNLESS
(
r
)
{
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
(
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
;
PyErr_Fetch
(
&
t
,
&
v
,
&
tb
);
if
(
t
==
PyExc_KeyError
&&
PyObject_Compare
(
v
,
oname
)
==
0
)
{
Py_DECREF
(
t
);
t
=
PyExc_AttributeError
;
Py_INCREF
(
t
);
}
PyErr_Restore
(
t
,
v
,
tb
);
return
NULL
;
}
}
if
(
PyFunction_Check
(
r
)
||
NeedsToBeBound
(
r
))
ASSIGN
(
r
,
newPMethod
(
self
,
r
));
else
if
(
PyMethod_Check
(
r
)
&&
!
PyMethod_Self
(
r
))
ASSIGN
(
r
,
newPMethod
(
self
,
PyMethod_Function
(
r
)));
return
r
;
}
static
PyObject
*
CCL_reduce
(
PyExtensionClass
*
self
,
PyObject
*
args
)
{
return
PyString_FromString
(
self
->
tp_name
);
}
PyObject
*
CCL_getattro
(
PyExtensionClass
*
self
,
PyObject
*
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
'b'
:
if
(
strcmp
(
n
,
"bases__"
)
==
0
)
{
if
(
self
->
bases
)
{
Py_INCREF
(
self
->
bases
);
return
self
->
bases
;
}
else
return
PyTuple_New
(
0
);
}
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
'c'
:
if
(
strcmp
(
n
,
"class__"
)
==
0
)
{
Py_INCREF
(
self
->
ob_type
);
return
OBJECT
(
self
->
ob_type
);
}
break
;
}
}
}
if
((
r
=
CCL_getattr
(
self
,
name
,
0
)))
{
if
(
UnboundCMethod_Check
(
r
)
&&
(
AsCMethod
(
r
)
->
flags
&
METH_CLASS_METHOD
))
ASSIGN
(
r
,(
PyObject
*
)
bindCMethod
((
CMethod
*
)
r
,
OBJECT
(
self
)));
}
return
r
;
}
static
int
CCL_setattro
(
PyExtensionClass
*
self
,
PyObject
*
name
,
PyObject
*
v
)
{
if
(
!
v
)
return
PyObject_DelItem
(
self
->
class_dictionary
,
name
);
if
(
v
&&
UnboundCMethod_Check
(
v
)
&&
!
(
self
->
class_flags
&
EXTENSIONCLASS_METHODHOOK_FLAG
)
)
{
char
*
n
;
PyNumberMethods
*
nm
;
PySequenceMethods
*
s
,
*
ms
;
PyMappingMethods
*
m
,
*
mm
;
UNLESS
(
n
=
PyString_AsString
(
name
))
return
-
1
;
if
(
*
n
++==
'_'
&&
*
n
++==
'_'
)
{
#define SET_SPECIAL(C,P) \
if (strcmp(n,#P "__")==0 \
&& AsCMethod(v)->meth==(PyCFunction)C ## _by_name \
&& Subclass_Check(self,AsCMethod(v)->type)) { \
self->tp_ ## C=AsCMethod(v)->type->tp_ ## C; \
return PyObject_SetItem(self->class_dictionary, name, v); }
/*
SET_SPECIAL(setattr,setattr);
SET_SPECIAL(setattro,setattr);
*/
SET_SPECIAL
(
compare
,
cmp
);
SET_SPECIAL
(
hash
,
hash
);
SET_SPECIAL
(
repr
,
repr
);
SET_SPECIAL
(
call
,
call
);
SET_SPECIAL
(
str
,
str
);
#undef SET_SPECIAL
#define SET_SPECIAL(C,P) \
if (strcmp(n,#P "__")==0 \
&& AsCMethod(v)->meth==(PyCFunction)C ## _by_name \
&& Subclass_Check(self,AsCMethod(v)->type) \
&& (nm=self->tp_as_number)) { \
nm->nb_ ## C=AsCMethod(v)->type->tp_as_number->nb_ ## C; \
return PyObject_SetItem(self->class_dictionary, name, v); }
SET_SPECIAL
(
add
,
add
);
SET_SPECIAL
(
subtract
,
sub
);
SET_SPECIAL
(
multiply
,
mult
);
SET_SPECIAL
(
divide
,
div
);
SET_SPECIAL
(
remainder
,
mod
);
SET_SPECIAL
(
power
,
pow
);
SET_SPECIAL
(
divmod
,
divmod
);
SET_SPECIAL
(
lshift
,
lshift
);
SET_SPECIAL
(
rshift
,
rshift
);
SET_SPECIAL
(
and
,
and
);
SET_SPECIAL
(
or
,
or
);
SET_SPECIAL
(
xor
,
xor
);
SET_SPECIAL
(
coerce
,
coerce
);
SET_SPECIAL
(
negative
,
neg
);
SET_SPECIAL
(
positive
,
pos
);
SET_SPECIAL
(
absolute
,
abs
);
SET_SPECIAL
(
nonzero
,
nonzero
);
SET_SPECIAL
(
invert
,
inv
);
SET_SPECIAL
(
int
,
int
);
SET_SPECIAL
(
long
,
long
);
SET_SPECIAL
(
float
,
float
);
SET_SPECIAL
(
oct
,
oct
);
SET_SPECIAL
(
hex
,
hex
);
#undef SET_SPECIAL
if
(
strcmp
(
n
,
"len__"
)
==
0
&&
AsCMethod
(
v
)
->
meth
==
(
PyCFunction
)
length_by_name
&&
Subclass_Check
(
self
,
AsCMethod
(
v
)
->
type
))
{
if
((
s
=
self
->
tp_as_sequence
)
&&
(
ms
=
AsCMethod
(
v
)
->
type
->
tp_as_sequence
)
&&
ms
->
sq_length
)
s
->
sq_length
=
ms
->
sq_length
;
if
((
m
=
self
->
tp_as_mapping
)
&&
(
mm
=
AsCMethod
(
v
)
->
type
->
tp_as_mapping
)
&&
mm
->
mp_length
)
m
->
mp_length
=
mm
->
mp_length
;
return
PyObject_SetItem
(
self
->
class_dictionary
,
name
,
v
);
}
if
(
strcmp
(
n
,
"getitem__"
)
==
0
&&
AsCMethod
(
v
)
->
meth
==
(
PyCFunction
)
getitem_by_name
&&
Subclass_Check
(
self
,
AsCMethod
(
v
)
->
type
))
{
if
((
s
=
self
->
tp_as_sequence
)
&&
(
ms
=
AsCMethod
(
v
)
->
type
->
tp_as_sequence
)
&&
ms
->
sq_item
)
s
->
sq_item
=
ms
->
sq_item
;
if
((
m
=
self
->
tp_as_mapping
)
&&
(
mm
=
AsCMethod
(
v
)
->
type
->
tp_as_mapping
)
&&
mm
->
mp_subscript
)
m
->
mp_subscript
=
mm
->
mp_subscript
;
return
PyObject_SetItem
(
self
->
class_dictionary
,
name
,
v
);
}
if
(
strcmp
(
n
,
"setitem__"
)
==
0
&&
AsCMethod
(
v
)
->
meth
==
(
PyCFunction
)
setitem_by_name
&&
Subclass_Check
(
self
,
AsCMethod
(
v
)
->
type
))
{
if
((
s
=
self
->
tp_as_sequence
)
&&
(
ms
=
AsCMethod
(
v
)
->
type
->
tp_as_sequence
)
&&
ms
->
sq_ass_item
)
s
->
sq_ass_item
=
ms
->
sq_ass_item
;
if
((
m
=
self
->
tp_as_mapping
)
&&
(
mm
=
AsCMethod
(
v
)
->
type
->
tp_as_mapping
)
&&
mm
->
mp_ass_subscript
)
m
->
mp_ass_subscript
=
mm
->
mp_ass_subscript
;
return
PyObject_SetItem
(
self
->
class_dictionary
,
name
,
v
);
}
#define SET_SPECIAL(C,P) \
if (strcmp(n,#P "__")==0 \
&& AsCMethod(v)->meth==(PyCFunction)C ## _by_name \
&& Subclass_Check(self,AsCMethod(v)->type) \
&& (s=self->tp_as_sequence)) { \
s->sq_ ## C=AsCMethod(v)->type->tp_as_sequence->sq_ ## C; \
return PyObject_SetItem(self->class_dictionary, name, v); }
SET_SPECIAL
(
slice
,
getslice
);
SET_SPECIAL
(
ass_slice
,
setslice
);
SET_SPECIAL
(
concat
,
concat
);
SET_SPECIAL
(
repeat
,
repeat
);
#undef SET_SPECIAL
}
}
return
PyObject_SetItem
(
self
->
class_dictionary
,
name
,
v
);
}
static
PyObject
*
CCL_call
(
PyExtensionClass
*
self
,
PyObject
*
arg
,
PyObject
*
kw
)
{
PyObject
*
inst
=
0
,
*
init
=
0
,
*
args
=
0
;
typedef
struct
{
PyObject_VAR_HEAD
}
PyVarObject__
;
if
(
!
self
->
tp_dealloc
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Attempt to create instance of an abstract type"
);
return
NULL
;
}
if
(
self
->
tp_itemsize
)
{
/* We have a variable-sized object, we need to get it's size */
PyObject
*
var_size
;
int
size
;
if
((
var_size
=
CCL_getattr
(
self
,
py__var_size__
,
0
)))
{
UNLESS_ASSIGN
(
var_size
,
PyObject_CallObject
(
var_size
,
arg
))
return
NULL
;
size
=
PyInt_AsLong
(
var_size
);
if
(
PyErr_Occurred
())
return
NULL
;
}
else
{
UNLESS
(
-
1
!=
(
size
=
PyTuple_Size
(
arg
)))
return
NULL
;
if
(
size
>
0
)
{
var_size
=
PyTuple_GET_ITEM
(
arg
,
0
);
if
(
PyInt_Check
(
var_size
))
size
=
PyInt_AsLong
(
var_size
);
else
size
=-
1
;
}
else
size
=-
1
;
if
(
size
<
0
)
{
PyErr_SetString
(
PyExc_TypeError
,
"object size expected as first argument"
);
return
NULL
;
}
}
UNLESS
(
inst
=
PyObject_NEW_VAR
(
PyObject
,(
PyTypeObject
*
)
self
,
size
))
return
NULL
;
memset
(
inst
,
0
,
self
->
tp_basicsize
+
self
->
tp_itemsize
*
size
);
((
PyVarObject__
*
)
inst
)
->
ob_size
=
size
;
}
else
{
UNLESS
(
inst
=
PyObject_NEW
(
PyObject
,(
PyTypeObject
*
)
self
))
return
NULL
;
memset
(
inst
,
0
,
self
->
tp_basicsize
);
}
inst
->
ob_refcnt
=
1
;
inst
->
ob_type
=
(
PyTypeObject
*
)
self
;
Py_INCREF
(
self
);
if
(
ClassHasInstDict
(
self
))
UNLESS
(
INSTANCE_DICT
(
inst
)
=
PyDict_New
())
goto
err
;
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
;
UNLESS_ASSIGN
(
args
,
PyEval_CallObjectWithKeywords
(
init
,
args
,
kw
))
goto
err
;
Py_DECREF
(
args
);
Py_DECREF
(
init
);
}
else
PyErr_Clear
();
if
(
self
->
bases
&&
subclass_watcher
&&
!
PyObject_CallMethod
(
subclass_watcher
,
"created"
,
"O"
,
inst
))
PyErr_Clear
();
return
inst
;
err:
Py_DECREF
(
inst
);
Py_XDECREF
(
init
);
Py_XDECREF
(
args
);
return
NULL
;
}
static
PyObject
*
CCL_repr
(
PyExtensionClass
*
self
)
{
char
p
[
128
],
*
pp
;
PyObject
*
m
;
if
((
m
=
PyObject_GetAttr
(
OBJECT
(
self
),
py__module__
)))
{
if
(
!
PyObject_IsTrue
(
m
))
{
Py_DECREF
(
m
);
m
=
0
;
}
}
else
PyErr_Clear
();
sprintf
(
p
,
"%p"
,
self
);
if
(
*
p
==
'0'
&&
p
[
1
]
==
'x'
)
pp
=
p
+
2
;
else
pp
=
p
;
if
(
m
)
ASSIGN
(
m
,
JimString_Build
(
"<extension class %s.%s at %s>"
,
"Oss"
,
m
,
self
->
tp_name
,
pp
));
else
m
=
JimString_Build
(
"<extension class %s at %s>"
,
"ss"
,
self
->
tp_name
,
pp
);
return
m
;
}
static
PyTypeObject
ECTypeType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"ExtensionClass Class"
,
/*tp_name*/
sizeof
(
PyExtensionClass
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
CCL_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
0
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
CCL_repr
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
CCL_call
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
(
getattrofunc
)
CCL_getattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
CCL_setattro
,
/*tp_setattr with object key*/
/* Space for future expansion */
0L
,
0L
,
"Class of C classes"
/* Documentation string */
};
/* End of code for ExtensionClass objects */
/* -------------------------------------------------------- */
/* subclassing code: */
static
PyObject
*
subclass_getspecial
(
PyObject
*
inst
,
PyObject
*
oname
)
{
PyObject
*
r
=
0
;
PyExtensionClass
*
self
;
self
=
(
PyExtensionClass
*
)(
inst
->
ob_type
);
if
(
HasInstDict
(
inst
))
{
r
=
INSTANCE_DICT
(
inst
);
r
=
PyObject_GetItem
(
r
,
oname
);
UNLESS
(
r
)
{
PyErr_Clear
();
r
=
CCL_getattr
(
self
,
oname
,
0
);
}
}
else
r
=
CCL_getattr
(
self
,
oname
,
0
);
return
r
;
}
static
PyObject
*
subclass_getattro
(
PyObject
*
self
,
PyObject
*
name
)
{
PyObject
*
r
;
if
(
!
name
)
return
NULL
;
UNLESS
(
r
=
EC_findiattro
(
self
,
name
))
{
PyErr_Clear
();
r
=
EC_findiattro
(
self
,
py__getattr__
);
if
(
r
)
ASSIGN
(
r
,
PyObject_CallFunction
(
r
,
"O"
,
name
));
if
(
r
&&
NeedsToBeBound
(
r
))
ASSIGN
(
r
,
CallMethodO
(
r
,
py__of__
,
Build
(
"(O)"
,
self
),
NULL
));
}
return
r
;
}
static
int
subclass_simple_setattro
(
PyObject
*
self
,
PyObject
*
name
,
PyObject
*
v
)
{
if
(
!
HasInstDict
(
self
))
{
PyErr_SetObject
(
PyExc_AttributeError
,
name
);
return
-
1
;
}
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
)
{
if
(
!
HasInstDict
(
self
))
{
PyErr_SetString
(
PyExc_AttributeError
,
name
);
return
-
1
;
}
if
(
v
)
return
PyDict_SetItemString
(
INSTANCE_DICT
(
self
),
name
,
v
);
else
return
PyDict_DelItemString
(
INSTANCE_DICT
(
self
),
name
);
}
static
int
subclass_setattr
(
PyObject
*
self
,
PyObject
*
oname
,
char
*
name
,
PyObject
*
v
)
{
PyObject
*
m
=
0
,
*
et
,
*
ev
,
*
etb
;
if
(
!
name
)
return
-
1
;
if
(
!
v
&&
(
m
=
subclass_getspecial
(
self
,
py__delattr__
)))
{
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
==
(
PyCFunction
)
setattr_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
UNLESS
(
-
1
!=
AsCMethod
(
m
)
->
type
->
tp_setattr
(
self
,
name
,
v
))
goto
dictionary_setattr
;
return
0
;
}
else
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
setattro_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
UNLESS
(
-
1
!=
AsCMethod
(
m
)
->
type
->
tp_setattro
(
self
,
oname
,
v
))
goto
dictionary_setattr
;
return
0
;
}
if
(
!
v
)
goto
default_setattr
;
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OOO"
,
self
,
oname
,
v
))
return
-
1
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
oname
,
v
))
return
-
1
;
Py_DECREF
(
m
);
return
0
;
dictionary_setattr:
Py_XDECREF
(
m
);
PyErr_Fetch
(
&
et
,
&
ev
,
&
etb
);
if
(
et
==
PyExc_AttributeError
)
{
char
*
s
;
if
(
ev
&&
PyString_Check
(
ev
)
&&
(
s
=
PyString_AsString
(
ev
))
&&
strcmp
(
s
,
name
)
==
0
)
{
Py_XDECREF
(
et
);
Py_XDECREF
(
ev
);
Py_XDECREF
(
etb
);
et
=
0
;
}
}
if
(
et
)
{
PyErr_Restore
(
et
,
ev
,
etb
);
return
-
1
;
}
default_setattr:
PyErr_Clear
();
return
subclass_simple_setattro
(
self
,
oname
,
v
);
}
static
int
subclass_setattro
(
PyObject
*
self
,
PyObject
*
name
,
PyObject
*
v
)
{
return
subclass_setattr
(
self
,
name
,
PyString_AsString
(
name
),
v
);
}
static
int
subclass_compare
(
PyObject
*
self
,
PyObject
*
v
)
{
PyObject
*
m
;
long
r
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__cmp__
))
{
PyErr_Clear
();
return
self
-
v
;
}
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
compare_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
self
))
r
=
AsCMethod
(
m
)
->
type
->
tp_compare
(
self
,
v
);
else
{
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
self
,
v
))
return
-
1
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
v
))
return
-
1
;
r
=
PyInt_AsLong
(
m
);
}
Py_DECREF
(
m
);
return
r
;
}
static
long
subclass_hash
(
PyObject
*
self
)
{
PyObject
*
m
;
long
r
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__hash__
))
return
-
1
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
hash_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
self
))
r
=
AsCMethod
(
m
)
->
type
->
tp_hash
(
self
);
else
{
if
(
UnboundEMethod_Check
(
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
;
}
static
PyObject
*
default_subclass_repr
(
PyObject
*
self
)
{
char
p
[
128
],
*
pp
;
PyErr_Clear
();
sprintf
(
p
,
"%p"
,
self
);
if
(
*
p
==
'0'
&&
p
[
1
]
==
'x'
)
pp
=
p
+
2
;
else
pp
=
p
;
return
JimString_Build
(
"<%s instance at %s>"
,
"ss"
,
self
->
ob_type
->
tp_name
,
pp
);
}
static
PyObject
*
subclass_repr
(
PyObject
*
self
)
{
PyObject
*
m
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__repr__
))
return
default_subclass_repr
(
self
);
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
repr_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
self
))
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_repr
(
self
));
else
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
self
));
else
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
""
));
return
m
;
}
static
PyObject
*
subclass_call
(
PyObject
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
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
)
&&
!
HasMethodHook
(
self
))
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_call
(
self
,
args
,
kw
));
else
{
if
(
UnboundEMethod_Check
(
m
))
{
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
);
}
else
ASSIGN
(
m
,
PyEval_CallObjectWithKeywords
(
m
,
args
,
kw
));
}
return
m
;
}
static
PyObject
*
subclass_str
(
PyObject
*
self
)
{
PyObject
*
m
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__str__
))
{
PyErr_Clear
();
return
subclass_repr
(
self
);
}
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
str_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
self
))
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_str
(
self
));
else
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
self
));
else
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
""
));
return
m
;
}
#define BINSUB(M,N,A) \
static PyObject * \
subclass_ ## M(PyObject *self, PyObject *v) \
{ \
PyObject *m; \
UNLESS(m=subclass_getspecial(self,py__ ## N ## __)) return NULL; \
if (UnboundCMethod_Check(m) \
&& AsCMethod(m)->meth==(PyCFunction)M ## _by_name \
&& SubclassInstance_Check(self,AsCMethod(m)->type) \
&& ! HasMethodHook(self)) \
ASSIGN(m,AsCMethod(m)->type->tp_as_number->nb_ ## M(self,v)); \
else if (UnboundEMethod_Check(m)) \
ASSIGN(m,PyObject_CallFunction(m,"OO",self,v)); \
else \
ASSIGN(m,PyObject_CallFunction(m,"O",v)); \
return m; \
}
static
PyObject
*
subclass_add
(
PyObject
*
self
,
PyObject
*
v
)
{
PyObject
*
m
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__add__
))
return
NULL
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
concat_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
self
))
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_concat
(
self
,
v
));
else
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
add_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
self
))
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_number
->
nb_add
(
self
,
v
));
else
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
self
,
v
));
else
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
v
));
return
m
;
}
BINSUB
(
subtract
,
sub
,
Subtract
)
static
PyObject
*
subclass_multiply
(
PyObject
*
self
,
PyObject
*
v
)
{
PyObject
*
m
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__mul__
))
return
NULL
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
repeat_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
self
))
{
int
i
;
i
=
PyInt_AsLong
(
v
);
if
(
i
==-
1
&&
PyErr_Occurred
())
return
NULL
;
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_repeat
(
self
,
i
));
}
else
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
multiply_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
self
))
ASSIGN
(
m
,
AsCMethod
(
m
)
->
type
->
tp_as_number
->
nb_multiply
(
self
,
v
));
else
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
self
,
v
));
else
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
v
));
return
m
;
}
BINSUB
(
divide
,
div
,
Divide
)
BINSUB
(
remainder
,
mod
,
Remainder
)
static
PyObject
*
subclass_power
(
PyObject
*
self
,
PyObject
*
v
,
PyObject
*
w
)
{
PyObject
*
m
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__pow__
))
return
NULL
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
power_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
self
))
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
)
BINSUB
(
and
,
and
,
And
)
BINSUB
(
or
,
or
,
Or
)
BINSUB
(
xor
,
xor
,
Xor
)
static
int
subclass_coerce
(
PyObject
**
self
,
PyObject
**
v
)
{
PyObject
*
m
;
int
r
;
UNLESS
(
m
=
subclass_getspecial
(
*
self
,
py__coerce__
))
{
PyErr_Clear
();
Py_INCREF
(
*
self
);
Py_INCREF
(
*
v
);
return
0
;
}
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
coerce_by_name
&&
SubclassInstance_Check
(
*
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
*
self
))
r
=
AsCMethod
(
m
)
->
type
->
tp_as_number
->
nb_coerce
(
self
,
v
);
else
{
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
*
self
,
*
v
));
else
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
*
v
));
UNLESS
(
m
)
return
-
1
;
if
(
m
==
Py_None
)
r
=-
1
;
else
{
if
(
PyArg_ParseTuple
(
m
,
"OO"
,
self
,
v
))
{
Py_INCREF
(
*
self
);
Py_INCREF
(
*
v
);
r
=
0
;
}
else
r
=-
1
;
}
}
Py_DECREF
(
m
);
return
r
;
}
#define UNSUB(M,N) \
static PyObject * \
subclass_ ## M(PyObject *self) \
{ \
PyObject *m; \
UNLESS(m=subclass_getspecial(self,py__ ## N ## __)) return NULL; \
if (UnboundCMethod_Check(m) \
&& AsCMethod(m)->meth==(PyCFunction)M ## _by_name \
&& SubclassInstance_Check(self,AsCMethod(m)->type) \
&& ! HasMethodHook(self)) \
ASSIGN(m,AsCMethod(m)->type->tp_as_number->nb_ ## M(self)); \
else if (UnboundEMethod_Check(m)) \
ASSIGN(m,PyObject_CallFunction(m,"O",self)); \
else \
ASSIGN(m,PyObject_CallFunction(m,"")); \
return m; \
}
UNSUB
(
negative
,
neg
)
UNSUB
(
positive
,
pos
)
UNSUB
(
absolute
,
abs
)
static
int
subclass_nonzero
(
PyObject
*
self
)
{
PyObject
*
m
;
long
r
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__nonzero__
))
{
/* We are being asked is we are true
Check out len, and if that fails, say we are true.
*/
PyErr_Clear
();
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__len__
))
{
PyErr_Clear
();
return
1
;
}
}
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
nonzero_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
self
))
r
=
AsCMethod
(
m
)
->
type
->
tp_as_number
->
nb_nonzero
(
self
);
else
{
if
(
UnboundEMethod_Check
(
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
;
}
UNSUB
(
invert
,
inv
)
UNSUB
(
int
,
int
)
UNSUB
(
long
,
long
)
UNSUB
(
float
,
float
)
UNSUB
(
oct
,
oct
)
UNSUB
(
hex
,
hex
)
#undef UNSUB
#undef BINSUB
static
PyNumberMethods
subclass_as_number
=
{
(
binaryfunc
)
subclass_add
,
/*nb_add*/
(
binaryfunc
)
subclass_subtract
,
/*nb_subtract*/
(
binaryfunc
)
subclass_multiply
,
/*nb_multiply*/
(
binaryfunc
)
subclass_divide
,
/*nb_divide*/
(
binaryfunc
)
subclass_remainder
,
/*nb_remainder*/
(
binaryfunc
)
subclass_divmod
,
/*nb_divmod*/
(
ternaryfunc
)
subclass_power
,
/*nb_power*/
(
unaryfunc
)
subclass_negative
,
/*nb_negative*/
(
unaryfunc
)
subclass_positive
,
/*nb_positive*/
(
unaryfunc
)
subclass_absolute
,
/*nb_absolute*/
(
inquiry
)
subclass_nonzero
,
/*nb_nonzero*/
(
unaryfunc
)
subclass_invert
,
/*nb_invert*/
(
binaryfunc
)
subclass_lshift
,
/*nb_lshift*/
(
binaryfunc
)
subclass_rshift
,
/*nb_rshift*/
(
binaryfunc
)
subclass_and
,
/*nb_and*/
(
binaryfunc
)
subclass_xor
,
/*nb_xor*/
(
binaryfunc
)
subclass_or
,
/*nb_or*/
(
coercion
)
subclass_coerce
,
/*nb_coerce*/
(
unaryfunc
)
subclass_int
,
/*nb_int*/
(
unaryfunc
)
subclass_long
,
/*nb_long*/
(
unaryfunc
)
subclass_float
,
/*nb_float*/
(
unaryfunc
)
subclass_oct
,
/*nb_oct*/
(
unaryfunc
)
subclass_hex
,
/*nb_hex*/
};
static
long
subclass_length
(
PyObject
*
self
)
{
PyObject
*
m
;
long
r
;
PyExtensionClass
*
t
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__len__
))
{
/* Hm. Maybe we are being checked to see if we are true.
Check to see if we have a __getitem__. If we don't, then
answer that we are true.
*/
PyErr_Clear
();
if
((
m
=
subclass_getspecial
(
self
,
py__getitem__
)))
{
/* Hm, we have getitem, must be error */
Py_DECREF
(
m
);
PyErr_SetObject
(
PyExc_AttributeError
,
py__len__
);
return
-
1
;
}
PyErr_Clear
();
return
subclass_nonzero
(
self
);
}
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
length_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
self
))
{
t
=
(
PyExtensionClass
*
)
AsCMethod
(
m
)
->
type
;
Py_DECREF
(
m
);
if
(
t
->
tp_as_sequence
)
return
t
->
tp_as_sequence
->
sq_length
(
self
);
else
return
t
->
tp_as_mapping
->
mp_length
(
self
);
}
if
(
UnboundEMethod_Check
(
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
;
}
static
PyObject
*
subclass_item
(
PyObject
*
self
,
int
index
)
{
PyObject
*
m
;
PyExtensionClass
*
t
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__getitem__
))
return
NULL
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
getitem_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
self
))
{
t
=
(
PyExtensionClass
*
)
AsCMethod
(
m
)
->
type
;
if
(
t
->
tp_as_sequence
&&
t
->
tp_as_sequence
->
sq_item
)
{
Py_DECREF
(
m
);
return
t
->
tp_as_sequence
->
sq_item
(
self
,
index
);
}
}
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
==
(
PyCFunction
)
slice_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
self
))
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
;
}
static
long
subclass_ass_item
(
PyObject
*
self
,
int
index
,
PyObject
*
v
)
{
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
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
self
))
{
t
=
(
PyExtensionClass
*
)
AsCMethod
(
m
)
->
type
;
if
(
t
->
tp_as_sequence
&&
t
->
tp_as_sequence
->
sq_ass_item
)
{
Py_DECREF
(
m
);
return
t
->
tp_as_sequence
->
sq_ass_item
(
self
,
index
,
v
);
}
}
if
(
!
v
)
{
PyErr_SetObject
(
PyExc_AttributeError
,
py__delitem__
);
return
-
1
;
}
if
(
UnboundEMethod_Check
(
m
))
{
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OiO"
,
self
,
index
,
v
))
return
-
1
;
}
else
UNLESS_ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"iO"
,
index
,
v
))
return
-
1
;
Py_DECREF
(
m
);
return
0
;
}
static
int
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
)
&&
!
HasMethodHook
(
self
))
{
r
=
AsCMethod
(
m
)
->
type
->
tp_as_sequence
->
sq_ass_slice
(
self
,
i1
,
i2
,
v
);
Py_DECREF
(
m
);
return
r
;
}
if
(
!
v
)
{
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
0
;
}
static
PyObject
*
subclass_repeat
(
PyObject
*
self
,
int
v
)
{
PyObject
*
m
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__mul__
))
return
NULL
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
repeat_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
self
))
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
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"i"
,
v
));
return
m
;
}
PySequenceMethods
subclass_as_sequence
=
{
(
inquiry
)
subclass_length
,
/*sq_length*/
(
binaryfunc
)
subclass_add
,
/*sq_concat*/
(
intargfunc
)
subclass_repeat
,
/*sq_repeat*/
(
intargfunc
)
subclass_item
,
/*sq_item*/
(
intintargfunc
)
subclass_slice
,
/*sq_slice*/
(
intobjargproc
)
subclass_ass_item
,
/*sq_ass_item*/
(
intintobjargproc
)
subclass_ass_slice
,
/*sq_ass_slice*/
};
static
PyObject
*
subclass_subscript
(
PyObject
*
self
,
PyObject
*
key
)
{
PyObject
*
m
;
PyExtensionClass
*
t
;
UNLESS
(
m
=
subclass_getspecial
(
self
,
py__getitem__
))
return
NULL
;
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
getitem_by_name
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
self
))
{
t
=
(
PyExtensionClass
*
)
AsCMethod
(
m
)
->
type
;
if
(
t
->
tp_as_mapping
&&
t
->
tp_as_mapping
->
mp_subscript
)
{
Py_DECREF
(
m
);
return
t
->
tp_as_mapping
->
mp_subscript
(
self
,
key
);
}
else
if
(
t
->
tp_as_sequence
&&
t
->
tp_as_sequence
->
sq_item
)
{
int
i
,
l
;
Py_DECREF
(
m
);
UNLESS
(
PyInt_Check
(
key
))
{
PyErr_SetString
(
PyExc_TypeError
,
"sequence subscript not int"
);
return
NULL
;
}
i
=
PyInt_AsLong
(
key
);
if
(
i
<
0
)
{
if
((
l
=
PyObject_Length
(
self
))
<
0
)
return
NULL
;
i
+=
l
;
}
return
t
->
tp_as_sequence
->
sq_item
(
self
,
i
);
}
}
if
(
UnboundEMethod_Check
(
m
))
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"OO"
,
self
,
key
));
else
ASSIGN
(
m
,
PyObject_CallFunction
(
m
,
"O"
,
key
));
return
m
;
}
static
long
subclass_ass_subscript
(
PyObject
*
self
,
PyObject
*
index
,
PyObject
*
v
)
{
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
&&
SubclassInstance_Check
(
self
,
AsCMethod
(
m
)
->
type
)
&&
!
HasMethodHook
(
self
))
{
t
=
(
PyExtensionClass
*
)
AsCMethod
(
m
)
->
type
;
if
(
t
->
tp_as_mapping
&&
t
->
tp_as_mapping
->
mp_ass_subscript
)
{
Py_DECREF
(
m
);
return
t
->
tp_as_mapping
->
mp_ass_subscript
(
self
,
index
,
v
);
}
else
if
(
t
->
tp_as_sequence
&&
t
->
tp_as_sequence
->
sq_ass_item
)
{
int
i
,
l
;
Py_DECREF
(
m
);
UNLESS
(
PyInt_Check
(
index
))
{
PyErr_SetString
(
PyExc_TypeError
,
"sequence subscript not int"
);
return
-
1
;
}
i
=
PyInt_AsLong
(
index
);
if
(
i
<
0
)
{
if
((
l
=
PyObject_Length
(
self
))
<
0
)
return
-
1
;
i
+=
l
;
}
return
t
->
tp_as_sequence
->
sq_ass_item
(
self
,
i
,
v
);
}
}
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
0
;
}
PyMappingMethods
subclass_as_mapping
=
{
(
inquiry
)
subclass_length
,
/*mp_length*/
(
binaryfunc
)
subclass_subscript
,
/*mp_subscript*/
(
objobjargproc
)
subclass_ass_subscript
,
/*mp_ass_subscript*/
};
static
int
dealloc_base
(
PyObject
*
inst
,
PyExtensionClass
*
self
)
{
int
i
,
l
;
PyObject
*
t
;
l
=
PyTuple_Size
(
self
->
bases
);
for
(
i
=
0
;
i
<
l
;
i
++
)
{
t
=
PyTuple_GET_ITEM
(
self
->
bases
,
i
);
if
(
ExtensionClass_Check
(
t
))
{
if
(
AsExtensionClass
(
t
)
->
bases
)
{
if
(
dealloc_base
(
inst
,
AsExtensionClass
(
t
)))
return
1
;
}
else
{
if
(((
PyExtensionClass
*
)
t
)
->
tp_dealloc
)
{
((
PyExtensionClass
*
)
t
)
->
tp_dealloc
(
inst
);
return
1
;
}
}
}
}
return
0
;
}
static
void
subclass_dealloc
(
PyObject
*
self
)
{
PyObject
*
m
,
*
t
,
*
v
,
*
tb
;
int
base_dealloced
;
#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
(
subclass_watcher
&&
!
PyObject_CallMethod
(
subclass_watcher
,
"destroying"
,
"O"
,
self
))
PyErr_Clear
();
if
((
m
=
subclass_getspecial
(
self
,
py__del__
)))
{
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 */
}
if
(
HasInstDict
(
self
))
{
Py_XDECREF
(
INSTANCE_DICT
(
self
));
}
/* See if there was a dealloc handler in a (C) base class.
If there was, then it deallocates the object and we
get a true value back.
Note that if there *is* a base class dealloc, then
*it* should decref the class.
*/
base_dealloced
=
dealloc_base
(
self
,(
PyExtensionClass
*
)
self
->
ob_type
);
/* We only deallocate ourselves if a base class didn't */
UNLESS
(
base_dealloced
)
{
Py_DECREF
(
self
->
ob_type
);
PyMem_DEL
(
self
);
}
PyErr_Restore
(
t
,
v
,
tb
);
}
static
void
datafull_baseclassesf
(
PyExtensionClass
*
type
,
PyObject
**
c1
,
PyObject
**
c2
)
{
/* Find the number of classes that have data and return them.
There should be no more than one.
*/
int
l
,
i
;
PyObject
*
base
;
l
=
PyTuple_Size
(
type
->
bases
);
for
(
i
=
0
;
i
<
l
&&
!
(
*
c1
&&
*
c2
);
i
++
)
{
base
=
PyTuple_GET_ITEM
(
type
->
bases
,
i
);
if
(
ExtensionClass_Check
(
base
))
{
if
(
AsExtensionClass
(
base
)
->
bases
)
datafull_baseclassesf
(
AsExtensionClass
(
base
),
c1
,
c2
);
else
{
if
(
AsExtensionClass
(
base
)
->
tp_basicsize
>
sizeof
(
PyPureMixinObject
)
||
AsExtensionClass
(
base
)
->
tp_itemsize
>
0
)
{
if
(
!
*
c1
)
*
c1
=
base
;
else
if
(
*
c1
!=
base
)
*
c2
=
base
;
}
}
}
}
}
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 baseclass that has data and. There should be only one. */
int
l
,
i
;
PyObject
*
base
,
*
dbase
;
l
=
PyTuple_Size
(
type
->
bases
);
for
(
i
=
0
;
i
<
l
;
i
++
)
{
base
=
PyTuple_GET_ITEM
(
type
->
bases
,
i
);
if
(
ExtensionClass_Check
(
base
))
{
if
(
AsExtensionClass
(
base
)
->
bases
)
{
if
((
dbase
=
datafull_baseclass
(
AsExtensionClass
(
base
))))
return
dbase
;
}
else
{
if
(
AsExtensionClass
(
base
)
->
tp_basicsize
>
sizeof
(
PyPureMixinObject
)
||
AsExtensionClass
(
base
)
->
tp_itemsize
>
0
)
return
base
;
}
}
}
return
NULL
;
}
static
PyObject
*
extension_baseclass
(
PyExtensionClass
*
type
)
{
/* Find the first immediate base class that is an extension class */
int
l
,
i
;
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
JimErr_Format
(
PyExc_TypeError
,
"No extension class found in subclass"
,
NULL
);
}
static
int
subclass_hasattr
(
PyExtensionClass
*
type
,
PyObject
*
name
)
{
PyObject
*
o
;
if
((
o
=
CCL_getattro
(
type
,
name
)))
{
Py_DECREF
(
o
);
return
1
;
}
PyErr_Clear
();
return
0
;
}
static
void
subclass_init_getattr
(
PyExtensionClass
*
self
,
PyObject
*
methods
)
{
PyObject
*
m
;
if
((
m
=
CCL_getattr
(
self
,
py__getattr__
,
0
)))
{
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
getattr_by_name
&&
Subclass_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
self
->
tp_getattr
=
AsCMethod
(
m
)
->
type
->
tp_getattr
;
}
else
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
getattro_by_name
&&
Subclass_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
self
->
tp_getattro
=
AsCMethod
(
m
)
->
type
->
tp_getattro
;
}
else
{
PyObject_SetItem
(
methods
,
py__getattr__
,
m
);
self
->
tp_getattro
=
subclass_getattro
;
}
Py_DECREF
(
m
);
}
else
{
PyErr_Clear
();
self
->
tp_getattro
=
EC_findiattro
;
}
}
static
void
subclass_init_setattr
(
PyExtensionClass
*
self
,
PyObject
*
methods
)
{
PyObject
*
m
;
if
((
m
=
CCL_getattr
(
self
,
py__setattr__
,
0
)))
{
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
setattr_by_name
&&
Subclass_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
self
->
tp_setattr
=
AsCMethod
(
m
)
->
type
->
tp_setattr
;
}
else
if
(
UnboundCMethod_Check
(
m
)
&&
AsCMethod
(
m
)
->
meth
==
(
PyCFunction
)
setattro_by_name
&&
Subclass_Check
(
self
,
AsCMethod
(
m
)
->
type
))
{
self
->
tp_setattro
=
AsCMethod
(
m
)
->
type
->
tp_setattro
;
}
else
{
PyObject_SetItem
(
methods
,
py__setattr__
,
m
);
self
->
tp_setattro
=
subclass_setattro
;
}
Py_DECREF
(
m
);
}
else
{
PyErr_Clear
();
self
->
tp_setattro
=
subclass_simple_setattro
;
}
}
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.
That is, we want to build a C class object that described a
subclass of a built-in type.
*/
static
PyObject
*
subclass__init__
(
PyExtensionClass
*
self
,
PyObject
*
args
)
{
PyObject
*
bases
,
*
methods
,
*
class_init
;
PyExtensionClass
*
type
;
char
*
name
,
*
p
;
int
l
;
UNLESS
(
PyArg_ParseTuple
(
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
))
{
PyErr_SetString
(
PyExc_TypeError
,
"second argument must be a tuple of 1 or more base classes"
);
}
self
->
bases
=
bases
;
Py_INCREF
(
bases
);
if
(
datafull_baseclasses
(
self
)
>
1
)
{
PyErr_SetString
(
PyExc_TypeError
,
"too many datafull base classes"
);
return
NULL
;
}
UNLESS
(
type
=
(
PyExtensionClass
*
)
datafull_baseclass
(
self
))
UNLESS
(
type
=
(
PyExtensionClass
*
)
extension_baseclass
(
self
))
return
NULL
;
self
->
tp_name
=
name
;
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
);
copy_member
(
tp_itemsize
);
copy_member
(
tp_print
);
self
->
tp_dealloc
=
subclass_dealloc
;
if
(
type
->
class_flags
&
EXTENSIONCLASS_PYTHONICATTR_FLAG
)
{
/* The base class wants subclass __get/setattr__ to have
Python class semantics and *it* will be providing them.
That means that we simply copy the base class
get/setattr.
*/
copy_member
(
tp_getattr
);
copy_member
(
tp_getattro
);
copy_member
(
tp_setattr
);
copy_member
(
tp_setattro
);
self
->
class_flags
|=
EXTENSIONCLASS_PYTHONICATTR_FLAG
;
if
(
CCL_hasattr
(
self
,
py__getattr__
))
self
->
class_flags
|=
EXTENSIONCLASS_USERGETATTR_FLAG
;
if
(
CCL_hasattr
(
self
,
py__setattr__
))
self
->
class_flags
|=
EXTENSIONCLASS_USERSETATTR_FLAG
;
if
(
CCL_hasattr
(
self
,
py__delattr__
))
self
->
class_flags
|=
EXTENSIONCLASS_USERDELATTR_FLAG
;
}
else
{
subclass_init_getattr
(
self
,
methods
);
subclass_init_setattr
(
self
,
methods
);
}
#define subclass_set(OP,N) \
self->tp_ ##OP = subclass_ ##OP
subclass_set
(
compare
,
cmp
);
subclass_set
(
repr
,
repr
);
if
(
subclass_hasattr
(
self
,
py__of__
))
self
->
class_flags
|=
EXTENSIONCLASS_BINDABLE_FLAG
;
if
(
subclass_hasattr
(
self
,
py__call_method__
))
self
->
class_flags
|=
EXTENSIONCLASS_METHODHOOK_FLAG
;
UNLESS
(
self
->
class_flags
&
EXTENSIONCLASS_NOINSTDICT_FLAG
)
self
->
class_flags
|=
EXTENSIONCLASS_INSTDICT_FLAG
;
if
(
type
->
bases
||
!
ClassHasInstDict
(
self
))
copy_member
(
tp_basicsize
);
else
{
self
->
tp_basicsize
=
type
->
tp_basicsize
/
sizeof
(
PyObject
*
)
*
sizeof
(
PyObject
*
);
if
(
self
->
tp_basicsize
<
type
->
tp_basicsize
)
self
->
tp_basicsize
+=
sizeof
(
PyObject
*
);
/* To align on PyObject */
self
->
tp_basicsize
+=
sizeof
(
PyObject
*
);
/* For instance dictionary */
}
self
->
tp_as_number
=
(
PyNumberMethods
*
)
malloc
(
sizeof
(
PyNumberMethods
));
UNLESS
(
self
->
tp_as_number
)
return
PyErr_NoMemory
();
*
(
self
->
tp_as_number
)
=
subclass_as_number
;
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
;
subclass_set
(
hash
,
hash
);
subclass_set
(
call
,
call
);
subclass_set
(
str
,
str
);
self
->
tp_doc
=
0
;
/* Implement __module__=__name__ */
if
(
PyDict_GetItem
(
methods
,
py__module__
)
==
NULL
)
{
PyObject
*
globals
=
PyEval_GetGlobals
();
if
(
globals
!=
NULL
)
{
PyObject
*
modname
=
PyDict_GetItem
(
globals
,
py__name__
);
if
(
modname
!=
NULL
)
{
if
(
PyDict_SetItem
(
methods
,
py__module__
,
modname
)
<
0
)
return
NULL
;
}
}
}
/* Check for and use __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
))
return
NULL
;
Py_DECREF
(
class_init
);
}
else
PyErr_Clear
();
Py_INCREF
(
Py_None
);
return
Py_None
;
}
struct
PyMethodDef
ExtensionClass_methods
[]
=
{
{
"__init__"
,(
PyCFunction
)
subclass__init__
,
1
,
""
},
{
NULL
,
NULL
}
/* sentinel */
};
static
PyExtensionClass
ECType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"ExtensionClass"
,
/*tp_name*/
sizeof
(
PyExtensionClass
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
CCL_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
0
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
CCL_repr
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
CCL_call
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
(
getattrofunc
)
CCL_getattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
CCL_setattro
,
/*tp_setattr with object key*/
/* Space for future expansion */
0L
,
0L
,
"C classes"
,
/* Documentation string */
METHOD_CHAIN
(
ExtensionClass_methods
)
};
/* List of methods defined in the module */
static
PyObject
*
set_subclass_watcher
(
PyObject
*
ignored
,
PyObject
*
args
)
{
PyObject
*
old
,
*
sw
=
0
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"|O"
,
&
sw
))
return
NULL
;
old
=
subclass_watcher
;
subclass_watcher
=
sw
;
if
(
sw
)
Py_INCREF
(
sw
);
if
(
old
)
return
old
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
struct
PyMethodDef
CC_methods
[]
=
{
{
"subclass_watcher"
,
(
PyCFunction
)
set_subclass_watcher
,
1
,
"subclass_watcher(ob) -- "
"Register an object to watch subclass instance events"
},
{
NULL
,
NULL
}
/* sentinel */
};
static
int
export_type
(
PyObject
*
dict
,
char
*
name
,
PyExtensionClass
*
typ
)
{
initializeBaseExtensionClass
(
typ
);
if
(
PyErr_Occurred
())
return
-
1
;
if
(
PyDict_GetItem
(
typ
->
class_dictionary
,
py__module__
)
==
NULL
)
{
PyObject
*
modname
=
PyDict_GetItem
(
dict
,
py__name__
);
if
(
modname
!=
NULL
)
{
if
(
PyDict_SetItem
(
typ
->
class_dictionary
,
py__module__
,
modname
)
<
0
)
return
-
1
;
}
}
PyErr_Clear
();
return
PyMapping_SetItemString
(
dict
,
name
,(
PyObject
*
)
typ
);
}
static
struct
ExtensionClassCAPIstruct
TrueExtensionClassCAPI
=
{
export_type
,
/* Export */
EC_findiattrs
,
/* getattrs */
EC_findiattro
,
/* getattro */
subclass_simple_setattr
,
/* setattrs */
subclass_simple_setattro
,
/* setattro */
(
PyObject
*
)
&
ECType
,
/* ExtensionClassType */
(
PyObject
*
)
&
PMethodType
,
/* MethodType */
PMethod_New
,
/* Method_New */
CMethod_issubclass
,
/* issubclass */
};
void
initExtensionClass
()
{
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.44 $"
;
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
;
UNLESS
(
concat_fmt
=
PyString_FromString
(
"%s%s"
));
m
=
Py_InitModule4
(
"ExtensionClass"
,
CC_methods
,
ExtensionClass_module_documentation
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
d
=
PyModule_GetDict
(
m
);
PyDict_SetItemString
(
d
,
"__version__"
,
PyString_FromStringAndSize
(
rev
+
11
,
strlen
(
rev
+
11
)
-
2
));
init_py_names
();
if
(
0
)
PyCObject_Import14
(
"this will go away"
,
"in 1.5 :-)"
);
initializeBaseExtensionClass
(
&
ECType
);
PyDict_SetItemString
(
d
,
"ExtensionClass"
,
(
PyObject
*
)
&
ECType
);
initializeBaseExtensionClass
(
&
BaseType
);
PyDict_SetItemString
(
d
,
"Base"
,
(
PyObject
*
)
&
BaseType
);
PyDict_SetItemString
(
d
,
"PythonMethodType"
,
(
PyObject
*
)
&
PMethodType
);
PyDict_SetItemString
(
d
,
"ExtensionMethodType"
,
(
PyObject
*
)
&
CMethodType
);
/* Export C attribute lookup API */
PyExtensionClassCAPI
=&
TrueExtensionClassCAPI
;
PyDict_SetItemString
(
d
,
"CAPI"
,
PyCObject_FromVoidPtr
(
PyExtensionClassCAPI
,
NULL
));
CHECK_FOR_ERRORS
(
"can't initialize module ExtensionClass"
);
}
lib/Components/ExtensionClass/ExtensionClass.h
deleted
100644 → 0
View file @
7dbb8830
/*
$Id: ExtensionClass.h,v 1.16 2000/12/26 15:17:59 jim Exp $
Extension Class Definitions
Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
o Redistributions of source code must retain the above copyright
notice, this list of conditions, and the disclaimer that follows.
o Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
o Neither the name of Digital Creations nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
Implementing base extension classes
A base extension class is implemented in much the same way that an
extension type is implemented, except:
- The include file, 'ExtensionClass.h', must be included.
- The type structure is declared to be of type
'PyExtensionClass', rather than of type 'PyTypeObject'.
- The type structure has an additional member that must be defined
after the documentation string. This extra member is a method chain
('PyMethodChain') containing a linked list of method definition
('PyMethodDef') lists. Method chains can be used to implement
method inheritance in C. Most extensions don't use method chains,
but simply define method lists, which are null-terminated arrays
of method definitions. A macro, 'METHOD_CHAIN' is defined in
'ExtensionClass.h' that converts a method list to a method chain.
(See the example below.)
- Module functions that create new instances must be replaced by an
'__init__' method that initializes, but does not create storage for
instances.
- The extension class must be initialized and exported to the module
with::
PyExtensionClass_Export(d,"name",type);
where 'name' is the module name and 'type' is the extension class
type object.
Attribute lookup
Attribute lookup is performed by calling the base extension class
'getattr' operation for the base extension class that includes C
data, or for the first base extension class, if none of the base
extension classes include C data. 'ExtensionClass.h' defines a
macro 'Py_FindAttrString' that can be used to find an object's
attributes that are stored in the object's instance dictionary or
in the object's class or base classes::
v = Py_FindAttrString(self,name);
In addition, a macro is provided that replaces 'Py_FindMethod'
calls with logic to perform the same sort of lookup that is
provided by 'Py_FindAttrString'.
Linking
The extension class mechanism was designed to be useful with
dynamically linked extension modules. Modules that implement
extension classes do not have to be linked against an extension
class library. The macro 'PyExtensionClass_Export' imports the
'ExtensionClass' module and uses objects imported from this module
to initialize an extension class with necessary behavior.
If you have questions regarding this software,
contact:
If you have questions regarding this software,
contact:
Digital Creations L.C.
info@digicool.com
(540) 371-6909
*/
#ifndef EXTENSIONCLASS_H
#define EXTENSIONCLASS_H
#include "Python.h"
#include "import.h"
/* Declarations for objects of type ExtensionClass */
typedef
struct
{
PyObject_VAR_HEAD
char
*
tp_name
;
/* For printing */
int
tp_basicsize
,
tp_itemsize
;
/* For allocation */
/* Methods to implement standard operations */
destructor
tp_dealloc
;
printfunc
tp_print
;
getattrfunc
tp_getattr
;
setattrfunc
tp_setattr
;
cmpfunc
tp_compare
;
reprfunc
tp_repr
;
/* Method suites for standard classes */
PyNumberMethods
*
tp_as_number
;
PySequenceMethods
*
tp_as_sequence
;
PyMappingMethods
*
tp_as_mapping
;
/* More standard operations (at end for binary compatibility) */
hashfunc
tp_hash
;
ternaryfunc
tp_call
;
reprfunc
tp_str
;
getattrofunc
tp_getattro
;
setattrofunc
tp_setattro
;
/* Space for future expansion */
long
tp_xxx3
;
long
tp_xxx4
;
char
*
tp_doc
;
/* Documentation string */
#ifdef COUNT_ALLOCS
/* these must be last */
int
tp_alloc
;
int
tp_free
;
int
tp_maxalloc
;
struct
_typeobject
*
tp_next
;
#endif
/* Here's the juicy stuff: */
/* Put your method chain here. If you just have a method
list, you can use the METHON_CHAIN macro to make a chain.
*/
PyMethodChain
methods
;
/* You may set certain flags here. */
long
class_flags
;
/* The following flags are used by ExtensionClass */
#define EXTENSIONCLASS_DYNAMIC_FLAG 1 << 0
#define EXTENSIONCLASS_BINDABLE_FLAG 1 << 2
#define EXTENSIONCLASS_METHODHOOK_FLAG 1 << 3
#define EXTENSIONCLASS_INSTDICT_FLAG 1 << 4
#define EXTENSIONCLASS_NOINSTDICT_FLAG 1 << 5
#define EXTENSIONCLASS_BASICNEW_FLAG 1 << 6
#define EXTENSIONCLASS_PYTHONICATTR_FLAG 1 << 7
#define EXTENSIONCLASS_USERGETATTR_FLAG 1 << 8
#define EXTENSIONCLASS_USERSETATTR_FLAG 1 << 9
#define EXTENSIONCLASS_USERDELATTR_FLAG 1 << 10
/* The following flags are for use by extension class developers. */
#define EXTENSIONCLASS_USER_FLAG1 1 << 16
#define EXTENSIONCLASS_USER_FLAG2 1 << 17
#define EXTENSIONCLASS_USER_FLAG3 1 << 18
#define EXTENSIONCLASS_USER_FLAG4 1 << 19
#define EXTENSIONCLASS_USER_FLAG5 1 << 20
#define EXTENSIONCLASS_USER_FLAG6 1 << 21
#define EXTENSIONCLASS_USER_FLAG7 1 << 22
#define EXTENSIONCLASS_USER_FLAG8 1 << 23
#define EXTENSIONCLASS_USER_FLAG9 1 << 24
#define EXTENSIONCLASS_USER_FLAG10 1 << 25
#define EXTENSIONCLASS_USER_FLAG11 1 << 26
#define EXTENSIONCLASS_USER_FLAG12 1 << 27
#define EXTENSIONCLASS_USER_FLAG13 1 << 28
#define EXTENSIONCLASS_USER_FLAG14 1 << 29
#define EXTENSIONCLASS_USER_FLAG15 1 << 30
#define EXTENSIONCLASS_USER_FLAG16 1 << 31
/* This is the class dictionary, which is normally created for you.
If you wish, you can provide your own class dictionary object.
If you do provide your own class dictionary, it *must* be
a mapping object. If the object given is also an extension
instance, then sub-class instance dictionaries will be created
by calling the class dictionary's class with zero argumemts.
Otherwise, subclass dictionaries will be of the default type.
*/
PyObject
*
class_dictionary
;
/* You should not set the remaining members. */
PyObject
*
bases
;
PyObject
*
reserved
;
}
PyExtensionClass
;
/* Following are macros that are needed or useful for defining extension
classes:
*/
/* This macro redefines Py_FindMethod to do attribute for an attribute
name given by a C string lookup using extension class meta-data.
This is used by older getattr implementations.
This macro is used in base class implementations of tp_getattr to
lookup methods or attributes that are not managed by the base type
directly. The macro is generally used to search for attributes
after other attribute searches have failed.
Note that in Python 1.4, a getattr operation may be provided that
uses an object argument. Classes that support this new operation
should use Py_FindAttr.
*/
#define Py_FindMethod(M,SELF,NAME) \
(PyExtensionClassCAPI->getattrs((SELF),(NAME)))
/* Do method or attribute lookup for an attribute name given by a C
string using extension class meta-data.
This macro is used in base class implementations of tp_getattro to
lookup methods or attributes that are not managed by the base type
directly. The macro is generally used to search for attributes
after other attribute searches have failed.
Note that in Python 1.4, a getattr operation may be provided that
uses an object argument. Classes that support this new operation
should use Py_FindAttr.
*/
#define Py_FindAttrString(SELF,NAME) \
(PyExtensionClassCAPI->getattrs((SELF),(NAME)))
/* Do method or attribute lookup using extension class meta-data.
This macro is used in base class implementations of tp_getattr to
lookup methods or attributes that are not managed by the base type
directly. The macro is generally used to search for attributes
after other attribute searches have failed. */
#define Py_FindAttr(SELF,NAME) (PyExtensionClassCAPI->getattro((SELF),(NAME)))
/* Do method or attribute assignment for an attribute name given by a
C string using extension class meta-data.
This macro is used in base class implementations of tp_setattr to
set attributes that are not managed by the base type directly. The
macro is generally used to assign attributes after other attribute
attempts to assign attributes have failed.
Note that in Python 1.4, a setattr operation may be provided that
uses an object argument. Classes that support this new operation
should use PyEC_SetAttr.
*/
#define PyEC_SetAttrString(SELF,NAME,V) \
(PyExtensionClassCAPI->setattrs((SELF),(NAME),(V)))
/* Do attribute assignment for an attribute.
This macro is used in base class implementations of tp_setattro to
set attributes that are not managed by the base type directly. The
macro is generally used to assign attributes after other attribute
attempts to assign attributes have failed.
*/
#define PyEC_SetAttr(SELF,NAME,V) \
(PyExtensionClassCAPI->setattro((SELF),(NAME),(V)))
/* Import the ExtensionClass CAPI */
#define ExtensionClassImported \
(PyExtensionClassCAPI=PyCObject_Import("ExtensionClass","CAPI"))
/* Make sure the C interface has been imported and import it if necessary.
This can be used in an if.
*/
#define MakeSureExtensionClassImported \
(PyExtensionClassCAPI || \
(PyExtensionClassCAPI=PyCObject_Import("ExtensionClass","CAPI")))
/* Export an Extension Base class in a given module dictionary with a
given name and ExtensionClass structure.
*/
#define PyExtensionClass_Export(D,N,T) \
if(PyExtensionClassCAPI || \
(PyExtensionClassCAPI= (struct ExtensionClassCAPIstruct*) \
PyCObject_Import("ExtensionClass","CAPI"))) \
{ PyExtensionClassCAPI->Export(D,N,&T); }
/* Convert a method list to a method chain. */
#define METHOD_CHAIN(DEF) { DEF, NULL }
/* The following macro checks whether a type is an extension class: */
#define PyExtensionClass_Check(TYPE) \
((PyObject*)(TYPE)->ob_type==PyExtensionClassCAPI->ExtensionClassType)
/* The following macro checks whether an instance is an extension instance: */
#define PyExtensionInstance_Check(INST) \
((PyObject*)(INST)->ob_type->ob_type== \
PyExtensionClassCAPI->ExtensionClassType)
/* The following macro checks for errors and prints out an error
message that is more informative than the one given by Python when
an extension module initialization fails.
*/
#define CHECK_FOR_ERRORS(MESS) \
if(PyErr_Occurred()) { \
PyObject *__sys_exc_type, *__sys_exc_value, *__sys_exc_traceback; \
PyErr_Fetch( &__sys_exc_type, &__sys_exc_value, \
&__sys_exc_traceback); \
fprintf(stderr, # MESS ":\n\t"); \
PyObject_Print(__sys_exc_type, stderr,0); \
fprintf(stderr,", "); \
PyObject_Print(__sys_exc_value, stderr,0); \
fprintf(stderr,"\n"); \
fflush(stderr); \
Py_FatalError(# MESS); \
}
/* The following macro can be used to define an extension base class
that only provides method and that is used as a pure mix-in class. */
#define PURE_MIXIN_CLASS(NAME,DOC,METHODS) \
static PyExtensionClass NAME ## Type = { PyObject_HEAD_INIT(NULL) \
0, # NAME, sizeof(PyPureMixinObject), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, DOC, {METHODS, NULL}, \
EXTENSIONCLASS_BASICNEW_FLAG}
/* The following macros provide limited access to extension-class
method facilities. */
/* Test for an ExtensionClass method: */
#define PyECMethod_Check(O) \
((PyObject*)(O)->ob_type==PyExtensionClassCAPI->MethodType)
/* Create a method object that wraps a callable object and an
instance. Note that if the callable object is an extension class
method, then the new method will wrap the callable object that is
wrapped by the extension class method. Also note that if the
callable object is an extension class method with a reference
count of 1, then the callable object will be rebound to the
instance and returned with an incremented reference count.
*/
#define PyECMethod_New(CALLABLE,INST) \
(PyExtensionClassCAPI->Method_New(CALLABLE,INST))
/* Return the instance that is bound by an extension class method. */
#define PyECMethod_Self(M) (((PyECMethodObject*)M)->self)
/* Check whether an object has an __of__ method for returning itself
in the context of it's container. */
#define has__of__(O) \
((O)->ob_type->ob_type == \
(PyTypeObject*)PyExtensionClassCAPI->ExtensionClassType && \
(((PyExtensionClass*)((O)->ob_type))->class_flags & \
EXTENSIONCLASS_BINDABLE_FLAG))
/* The following macros are used to check whether an instance
or a class' instanses have instance dictionaries: */
#define HasInstDict(O) \
((((PyExtensionClass*)((O)->ob_type))->class_flags & \
EXTENSIONCLASS_INSTDICT_FLAG))
#define ClassHasInstDict(O) (O->class_flags & EXTENSIONCLASS_INSTDICT_FLAG)
/* Get an object's instance dictionary. Use with caution */
#define INSTANCE_DICT(inst) \
*(((PyObject**)inst) + (inst->ob_type->tp_basicsize/sizeof(PyObject*) - 1))
/* Test whether an ExtensionClass, S, is a subclass of ExtensionClass C. */
#define ExtensionClassSubclass_Check(S,C) ( \
((PyObject*)(S)->ob_type==PyExtensionClassCAPI->ExtensionClassType) && \
((PyObject*)(C)->ob_type==PyExtensionClassCAPI->ExtensionClassType) && \
(PyExtensionClassCAPI->issubclass((PyExtensionClass *)(S), \
(PyExtensionClass *)(C))))
/* Test whether an ExtensionClass instance , I, is a subclass of
ExtensionClass C. */
#define ExtensionClassSubclassInstance_Check(I,C) ( \
((PyObject*)(I)->ob_type->ob_type== \
PyExtensionClassCAPI->ExtensionClassType) && \
((PyObject*)(C)->ob_type==PyExtensionClassCAPI->ExtensionClassType) && \
(PyExtensionClassCAPI->issubclass((PyExtensionClass *)((I)->ob_type), \
(PyExtensionClass *)(C))))
/* This let's you define built-in class methods. */
#define METH_CLASS_METHOD (2 << 17)
/*****************************************************************************
WARNING: EVERYTHING BELOW HERE IS PRIVATE TO THE EXTENSION CLASS INTERFACE
IMPLEMENTATION AND IS SUBJECT TO CHANGE !!!
*****************************************************************************/
static
struct
ExtensionClassCAPIstruct
{
int
(
*
Export
)(
PyObject
*
dict
,
char
*
name
,
PyExtensionClass
*
ob_type
);
PyObject
*
(
*
getattrs
)(
PyObject
*
,
char
*
);
PyObject
*
(
*
getattro
)(
PyObject
*
,
PyObject
*
);
int
(
*
setattrs
)(
PyObject
*
,
char
*
,
PyObject
*
);
int
(
*
setattro
)(
PyObject
*
,
PyObject
*
,
PyObject
*
);
PyObject
*
ExtensionClassType
;
PyObject
*
MethodType
;
PyObject
*
(
*
Method_New
)(
PyObject
*
callable
,
PyObject
*
inst
);
int
(
*
issubclass
)(
PyExtensionClass
*
sub
,
PyExtensionClass
*
type
);
}
*
PyExtensionClassCAPI
=
NULL
;
typedef
struct
{
PyObject_HEAD
}
PyPureMixinObject
;
typedef
struct
{
PyObject_HEAD
PyTypeObject
*
type
;
PyObject
*
self
;
PyObject
*
meth
;
}
PyECMethodObject
;
/* AKA PMethod */
/* The following is to avoid whining from 1.5 :-) */
#define PyCObject_Import PyCObject_Import14
static
void
*
PyCObject_Import14
(
char
*
module_name
,
char
*
name
)
{
PyObject
*
m
,
*
c
;
void
*
r
=
NULL
;
if
((
m
=
PyImport_ImportModule
(
module_name
)))
{
if
((
c
=
PyObject_GetAttrString
(
m
,
name
)))
{
r
=
PyCObject_AsVoidPtr
(
c
);
Py_DECREF
(
c
);
}
Py_DECREF
(
m
);
}
return
r
;
}
#endif
lib/Components/ExtensionClass/MethodObject.c
deleted
100644 → 0
View file @
7dbb8830
/*
Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
o Redistributions of source code must retain the above copyright
notice, this list of conditions, and the disclaimer that follows.
o Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
o Neither the name of Digital Creations nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
$Id: MethodObject.c,v 1.5 1998/11/17 19:50:20 jim Exp $
If you have questions regarding this software,
contact:
Digital Creations L.C.
info@digicool.com
(540) 371-6909
*/
#include "ExtensionClass.h"
static
PyObject
*
of
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
inst
;
if
(
PyArg_Parse
(
args
,
"O"
,
&
inst
))
return
PyECMethod_New
(
self
,
inst
);
else
return
NULL
;
}
struct
PyMethodDef
Method_methods
[]
=
{
{
"__of__"
,(
PyCFunction
)
of
,
0
,
""
},
{
NULL
,
NULL
}
/* sentinel */
};
static
struct
PyMethodDef
methods
[]
=
{{
NULL
,
NULL
}};
void
initMethodObject
()
{
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.5 $"
;
PURE_MIXIN_CLASS
(
Method
,
"Base class for objects that want to be treated as methods
\n
"
"
\n
"
"The method class provides a method, __of__, 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_methods
);
/* Create the module and add the functions */
m
=
Py_InitModule4
(
"MethodObject"
,
methods
,
"Method-object mix-in class module
\n\n
"
"$Id: MethodObject.c,v 1.5 1998/11/17 19:50:20 jim Exp $
\n
"
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
d
=
PyModule_GetDict
(
m
);
PyExtensionClass_Export
(
d
,
"Method"
,
MethodType
);
PyDict_SetItemString
(
d
,
"__version__"
,
PyString_FromStringAndSize
(
rev
+
11
,
strlen
(
rev
+
11
)
-
2
));
/* Check for errors */
CHECK_FOR_ERRORS
(
"can't initialize module MethodObject"
);
}
lib/Components/ExtensionClass/Missing.c
deleted
100644 → 0
View file @
7dbb8830
/*
Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
o Redistributions of source code must retain the above copyright
notice, this list of conditions, and the disclaimer that follows.
o Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
o Neither the name of Digital Creations nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
$Id: Missing.c,v 1.10 1999/08/25 20:15:29 jim Exp $
If you have questions regarding this software,
contact:
Digital Creations L.C.
info@digicool.com
(540) 371-6909
*/
static
char
Missing_module_documentation
[]
=
""
"
\n
$Id: Missing.c,v 1.10 1999/08/25 20:15:29 jim Exp $"
;
#include <string.h>
#include "ExtensionClass.h"
/* Declarations for objects of type Missing */
typedef
struct
{
PyObject_HEAD
}
Missing
;
static
PyObject
*
vname
=
0
,
*
Missing_dot_Value
=
0
,
*
empty_string
=
0
,
*
reduce
=
0
;
static
PyObject
*
theValue
;
static
void
Missing_dealloc
(
Missing
*
self
)
{
Py_DECREF
(
self
->
ob_type
);
PyMem_DEL
(
self
);
}
static
PyObject
*
Missing_repr
(
Missing
*
self
)
{
Py_INCREF
(
Missing_dot_Value
);
return
Missing_dot_Value
;
}
static
PyObject
*
Missing_str
(
Missing
*
self
)
{
Py_INCREF
(
empty_string
);
return
empty_string
;
}
/* Code to access Missing objects as numbers */
static
PyObject
*
Missing_bin
(
PyObject
*
v
,
PyObject
*
w
)
{
Py_INCREF
(
v
);
return
v
;
}
static
PyObject
*
Missing_pow
(
PyObject
*
v
,
PyObject
*
w
,
PyObject
*
z
)
{
Py_INCREF
(
v
);
return
v
;
}
static
PyObject
*
Missing_un
(
PyObject
*
v
)
{
Py_INCREF
(
v
);
return
v
;
}
static
int
Missing_nonzero
(
PyObject
*
v
)
{
return
0
;
}
static
int
Missing_coerce
(
PyObject
**
pv
,
PyObject
**
pw
)
{
Py_INCREF
(
*
pv
);
Py_INCREF
(
*
pw
);
return
0
;
}
static
PyObject
*
Missing_int
(
Missing
*
v
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Missing objects do not support conversion to integer"
);
return
NULL
;
}
static
PyObject
*
Missing_long
(
Missing
*
v
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Missing objects do not support conversion to long"
);
return
NULL
;
}
static
PyObject
*
Missing_float
(
Missing
*
v
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Missing objects do not support conversion to float"
);
return
NULL
;
}
static
PyObject
*
Missing_oct
(
Missing
*
v
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Missing objects do not support conversion to an octal string"
);
return
NULL
;
}
static
PyObject
*
Missing_hex
(
Missing
*
v
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Missing objects do not support conversion to hexadecimal strings"
);
return
NULL
;
}
static
PyNumberMethods
Missing_as_number
=
{
(
binaryfunc
)
Missing_bin
,
/*nb_add*/
(
binaryfunc
)
Missing_bin
,
/*nb_subtract*/
(
binaryfunc
)
Missing_bin
,
/*nb_multiply*/
(
binaryfunc
)
Missing_bin
,
/*nb_divide*/
(
binaryfunc
)
Missing_bin
,
/*nb_remainder*/
(
binaryfunc
)
Missing_bin
,
/*nb_divmod*/
(
ternaryfunc
)
Missing_pow
,
/*nb_power*/
(
unaryfunc
)
Missing_un
,
/*nb_negative*/
(
unaryfunc
)
Missing_un
,
/*nb_positive*/
(
unaryfunc
)
Missing_un
,
/*nb_absolute*/
(
inquiry
)
Missing_nonzero
,
/*nb_nonzero*/
(
unaryfunc
)
Missing_un
,
/*nb_invert*/
(
binaryfunc
)
Missing_bin
,
/*nb_lshift*/
(
binaryfunc
)
Missing_bin
,
/*nb_rshift*/
(
binaryfunc
)
Missing_bin
,
/*nb_and*/
(
binaryfunc
)
Missing_bin
,
/*nb_xor*/
(
binaryfunc
)
Missing_bin
,
/*nb_or*/
(
coercion
)
Missing_coerce
,
/*nb_coerce*/
(
unaryfunc
)
Missing_int
,
/*nb_int*/
(
unaryfunc
)
Missing_long
,
/*nb_long*/
(
unaryfunc
)
Missing_float
,
/*nb_float*/
(
unaryfunc
)
Missing_oct
,
/*nb_oct*/
(
unaryfunc
)
Missing_hex
,
/*nb_hex*/
};
/* ------------------------------------------------------- */
static
PyObject
*
Missing_reduce
(
PyObject
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
if
(
self
==
theValue
)
{
Py_INCREF
(
vname
);
return
vname
;
}
return
Py_BuildValue
(
"O()"
,
self
->
ob_type
);
}
static
struct
PyMethodDef
reduce_ml
[]
=
{
{
"__reduce__"
,
(
PyCFunction
)
Missing_reduce
,
1
,
"Return a missing value reduced to standard python objects"
}
};
static
PyObject
*
Missing_getattr
(
PyObject
*
self
,
PyObject
*
name
)
{
char
*
c
,
*
legal
;
if
(
!
(
c
=
PyString_AsString
(
name
)))
return
NULL
;
legal
=
c
;
if
(
strchr
(
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
,
*
legal
)
!=
NULL
)
{
for
(
legal
++
;
*
legal
;
legal
++
)
if
(
strchr
(
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"
,
*
legal
)
==
NULL
)
{
legal
=
NULL
;
break
;
}
}
else
legal
=
NULL
;
if
(
!
legal
)
{
if
(
strcmp
(
c
,
"__reduce__"
)
==
0
)
{
if
(
self
==
theValue
)
{
Py_INCREF
(
reduce
);
return
reduce
;
}
return
PyCFunction_New
(
reduce_ml
,
self
);
}
PyErr_SetObject
(
PyExc_AttributeError
,
name
);
return
NULL
;
}
Py_INCREF
(
self
);
return
self
;
}
static
PyObject
*
Missing_call
(
PyObject
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
Py_INCREF
(
self
);
return
self
;
}
static
int
Missing_cmp
(
Missing
*
m1
,
Missing
*
m2
)
{
return
m1
->
ob_type
!=
m2
->
ob_type
;
}
static
PyExtensionClass
MissingType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"Missing"
,
/*tp_name*/
sizeof
(
Missing
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
Missing_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
0
,
/*obsolete tp_getattr*/
(
setattrfunc
)
0
,
/*obsolete tp_setattr*/
(
cmpfunc
)
Missing_cmp
,
/*tp_compare*/
(
reprfunc
)
Missing_repr
,
/*tp_repr*/
&
Missing_as_number
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
Missing_call
,
/*tp_call*/
(
reprfunc
)
Missing_str
,
/*tp_str*/
(
getattrofunc
)
Missing_getattr
,
/*tp_getattro*/
(
setattrofunc
)
0
,
/*tp_setattro*/
/* Space for future expansion */
0L
,
0L
,
"Represent totally unknown quantities
\n
"
"
\n
"
"Missing values are used to represent numberic quantities that are
\n
"
"unknown. They support all mathematical operations except
\n
"
"conversions by returning themselves.
\n
"
,
METHOD_CHAIN
(
NULL
)
};
/* End of code for Missing objects */
/* -------------------------------------------------------- */
/* List of methods defined in the module */
static
struct
PyMethodDef
Module_Level__methods
[]
=
{
{
NULL
,
(
PyCFunction
)
NULL
,
0
,
NULL
}
/* sentinel */
};
void
initMissing
()
{
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.10 $"
;
if
(
!
((
vname
=
PyString_FromString
(
"V"
))
&&
(
Missing_dot_Value
=
PyString_FromString
(
"Missing.Value"
))
&&
(
empty_string
=
PyString_FromString
(
""
))
))
return
;
/* Create the module and add the functions */
m
=
Py_InitModule4
(
"Missing"
,
Module_Level__methods
,
Missing_module_documentation
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
/* Add some symbolic constants to the module */
d
=
PyModule_GetDict
(
m
);
PyDict_SetItemString
(
d
,
"__version__"
,
PyString_FromStringAndSize
(
rev
+
11
,
strlen
(
rev
+
11
)
-
2
));
PyExtensionClass_Export
(
d
,
"Missing"
,
MissingType
);
theValue
=
PyObject_CallObject
((
PyObject
*
)
&
MissingType
,
NULL
);
reduce
=
PyCFunction_New
(
reduce_ml
,
theValue
);
PyDict_SetItemString
(
d
,
"Value"
,
theValue
);
PyDict_SetItemString
(
d
,
"V"
,
theValue
);
PyDict_SetItemString
(
d
,
"MV"
,
theValue
);
/* Check for errors */
if
(
PyErr_Occurred
())
Py_FatalError
(
"can't initialize module Missing"
);
}
/*****************************************************************************
Revision Log:
$Log: Missing.c,v $
Revision 1.10 1999/08/25 20:15:29 jim
Made getattr a bit pickler to prevent getting attributes like "%f5.3".
Revision 1.9 1999/06/10 20:09:47 jim
Updated to use new ExtensionClass destructor protocol.
Revision 1.8 1998/11/17 19:54:33 jim
new copyright.
Revision 1.7 1997/10/03 14:43:27 jim
Fixed comparison bug, again :-(
Revision 1.6 1997/09/23 16:06:03 jim
Added MV member.
Revision 1.5 1997/09/23 15:17:12 jim
Added cmp.
Revision 1.4 1997/09/18 21:01:33 jim
Added check to getattr to fail on methods that begin with underscore.
Note that Missing really defeats testing from protocols by testing for
attributes.
Revision 1.3 1997/09/17 22:49:35 jim
Fixed refcount bug.
Added logic so: Missing.Value.spam() returns Missing.Value.
Added logic to make Missing.Value picklable.
Revision 1.2 1997/07/02 20:19:37 jim
Got rid of unused macros and ErrorObject.
Revision 1.1 1997/07/01 21:36:34 jim
*****************************************************************************/
lib/Components/ExtensionClass/MultiMapping.c
deleted
100644 → 0
View file @
7dbb8830
/*
Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
o Redistributions of source code must retain the above copyright
notice, this list of conditions, and the disclaimer that follows.
o Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
o Neither the name of Digital Creations nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
$Id: MultiMapping.c,v 1.8 1999/06/10 20:10:46 jim Exp $
If you have questions regarding this software,
contact:
Digital Creations L.C.
info@digicool.com
(540) 371-6909
*/
#include "Python.h"
#include "ExtensionClass.h"
#define UNLESS(E) if(!(E))
typedef
struct
{
PyObject_HEAD
PyObject
*
data
;
}
MMobject
;
staticforward
PyExtensionClass
MMtype
;
static
PyObject
*
MM_push
(
MMobject
*
self
,
PyObject
*
args
)
{
PyObject
*
src
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
src
))
return
NULL
;
UNLESS
(
-
1
!=
PyList_Append
(
self
->
data
,
src
))
return
NULL
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyObject
*
MM_pop
(
MMobject
*
self
,
PyObject
*
args
)
{
int
i
=
1
,
l
;
PyObject
*
r
;
if
(
args
)
UNLESS
(
PyArg_ParseTuple
(
args
,
"|i"
,
&
i
))
return
NULL
;
if
((
l
=
PyList_Size
(
self
->
data
))
<
0
)
return
NULL
;
i
=
l
-
i
;
UNLESS
(
r
=
PySequence_GetItem
(
self
->
data
,
l
-
1
))
return
NULL
;
if
(
PyList_SetSlice
(
self
->
data
,
i
,
l
,
NULL
)
<
0
)
goto
err
;
return
r
;
err:
Py_DECREF
(
r
);
return
NULL
;
}
static
PyObject
*
MM__init__
(
MMobject
*
self
,
PyObject
*
args
)
{
UNLESS
(
self
->
data
=
PyList_New
(
0
))
return
NULL
;
if
(
args
)
{
int
l
,
i
;
if
((
l
=
PyTuple_Size
(
args
))
<
0
)
return
NULL
;
for
(
i
=
0
;
i
<
l
;
i
++
)
if
(
PyList_Append
(
self
->
data
,
PyTuple_GET_ITEM
(
args
,
i
))
<
0
)
return
NULL
;
}
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyObject
*
MM_subscript
(
MMobject
*
self
,
PyObject
*
key
)
{
long
i
;
PyObject
*
e
;
UNLESS
(
-
1
!=
(
i
=
PyList_Size
(
self
->
data
)))
return
NULL
;
while
(
--
i
>=
0
)
{
e
=
PyList_GetItem
(
self
->
data
,
i
);
if
((
e
=
PyObject_GetItem
(
e
,
key
)))
return
e
;
PyErr_Clear
();
}
PyErr_SetObject
(
PyExc_KeyError
,
key
);
return
NULL
;
}
static
PyObject
*
MM_has_key
(
MMobject
*
self
,
PyObject
*
args
)
{
PyObject
*
key
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
key
))
return
NULL
;
if
((
key
=
MM_subscript
(
self
,
key
)))
{
Py_DECREF
(
key
);
return
PyInt_FromLong
(
1
);
}
PyErr_Clear
();
return
PyInt_FromLong
(
0
);
}
static
PyObject
*
MM_get
(
MMobject
*
self
,
PyObject
*
args
)
{
PyObject
*
key
,
*
d
=
Py_None
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O|O"
,
&
key
,
&
d
))
return
NULL
;
if
((
key
=
MM_subscript
(
self
,
key
)))
return
key
;
PyErr_Clear
();
Py_INCREF
(
d
);
return
d
;
}
static
struct
PyMethodDef
MM_methods
[]
=
{
{
"__init__"
,
(
PyCFunction
)
MM__init__
,
METH_VARARGS
,
"__init__([m1, m2, ...]) -- Create a new empty multi-mapping"
},
{
"get"
,
(
PyCFunction
)
MM_get
,
METH_VARARGS
,
"get(key,[default]) -- Return a value for the given key or a default"
},
{
"has_key"
,
(
PyCFunction
)
MM_has_key
,
METH_VARARGS
,
"has_key(key) -- Return 1 if the mapping has the key, and 0 otherwise"
},
{
"push"
,
(
PyCFunction
)
MM_push
,
METH_VARARGS
,
"push(mapping_object) -- Add a data source"
},
{
"pop"
,
(
PyCFunction
)
MM_pop
,
METH_VARARGS
,
"pop([n]) -- Remove and return the last data source added"
},
{
NULL
,
NULL
}
/* sentinel */
};
static
void
MM_dealloc
(
MMobject
*
self
)
{
Py_XDECREF
(
self
->
data
);
Py_DECREF
(
self
->
ob_type
);
PyMem_DEL
(
self
);
}
static
PyObject
*
MM_getattr
(
MMobject
*
self
,
char
*
name
)
{
return
Py_FindMethod
(
MM_methods
,
(
PyObject
*
)
self
,
name
);
}
static
int
MM_length
(
MMobject
*
self
)
{
long
l
=
0
,
el
,
i
;
PyObject
*
e
=
0
;
UNLESS
(
-
1
!=
(
i
=
PyList_Size
(
self
->
data
)))
return
-
1
;
while
(
--
i
>=
0
)
{
e
=
PyList_GetItem
(
self
->
data
,
i
);
UNLESS
(
-
1
!=
(
el
=
PyObject_Length
(
e
)))
return
-
1
;
l
+=
el
;
}
return
l
;
}
static
PyMappingMethods
MM_as_mapping
=
{
(
inquiry
)
MM_length
,
/*mp_length*/
(
binaryfunc
)
MM_subscript
,
/*mp_subscript*/
(
objobjargproc
)
NULL
,
/*mp_ass_subscript*/
};
/* -------------------------------------------------------- */
static
char
MMtype__doc__
[]
=
"MultiMapping -- Combine multiple mapping objects for lookup"
;
static
PyExtensionClass
MMtype
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"MultiMapping"
,
/*tp_name*/
sizeof
(
MMobject
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
MM_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
MM_getattr
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
&
MM_as_mapping
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
0
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
/* Space for future expansion */
0L
,
0L
,
0L
,
0L
,
MMtype__doc__
,
/* Documentation string */
METHOD_CHAIN
(
MM_methods
)
};
static
struct
PyMethodDef
MultiMapping_methods
[]
=
{
{
NULL
,
NULL
}
/* sentinel */
};
void
initMultiMapping
()
{
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.8 $"
;
m
=
Py_InitModule4
(
"MultiMapping"
,
MultiMapping_methods
,
"MultiMapping -- Wrap multiple mapping objects for lookup"
"
\n\n
"
"$Id: MultiMapping.c,v 1.8 1999/06/10 20:10:46 jim Exp $
\n
"
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
d
=
PyModule_GetDict
(
m
);
PyExtensionClass_Export
(
d
,
"MultiMapping"
,
MMtype
);
PyDict_SetItemString
(
d
,
"__version__"
,
PyString_FromStringAndSize
(
rev
+
11
,
strlen
(
rev
+
11
)
-
2
));
if
(
PyErr_Occurred
())
Py_FatalError
(
"can't initialize module MultiMapping"
);
}
lib/Components/ExtensionClass/Record.c
deleted
100644 → 0
View file @
7dbb8830
/*****************************************************************************
Zope Public License (ZPL) Version 1.0
-------------------------------------
Copyright (c) Digital Creations. All rights reserved.
This license has been certified as Open Source(tm).
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions in source code must retain the above copyright
notice, this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. Digital Creations requests that attribution be given to Zope
in any manner possible. Zope includes a "Powered by Zope"
button that is installed by default. While it is not a license
violation to remove this button, it is requested that the
attribution remain. A significant investment has been put
into Zope, and this effort will continue if the Zope community
continues to grow. This is one way to assure that growth.
4. All advertising materials and documentation mentioning
features derived from or use of this software must display
the following acknowledgement:
"This product includes software developed by Digital Creations
for use in the Z Object Publishing Environment
(http://www.zope.org/)."
In the event that the product being advertised includes an
intact Zope distribution (with copyright and license included)
then this clause is waived.
5. Names associated with Zope or Digital Creations must not be used to
endorse or promote products derived from this software without
prior written permission from Digital Creations.
6. Modified redistributions of any form whatsoever must retain
the following acknowledgment:
"This product includes software developed by Digital Creations
for use in the Z Object Publishing Environment
(http://www.zope.org/)."
Intact (re-)distributions of any official Zope release do not
require an external acknowledgement.
7. Modifications are encouraged but must be packaged separately as
patches to official Zope releases. Distributions that do not
clearly separate the patches from the original work must be clearly
labeled as unofficial distributions. Modifications which do not
carry the name Zope may be packaged in any form, as long as they
conform to all of the clauses above.
Disclaimer
THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
This software consists of contributions made by Digital Creations and
many individuals on behalf of Digital Creations. Specific
attributions are listed in the accompanying credits file.
****************************************************************************/
static
char
Record_module_documentation
[]
=
""
"
\n
$Id: Record.c,v 1.10 2001/02/19 19:16:07 jeremy Exp $"
;
#ifdef PERSISTENCE
#include "cPersistence.h"
#else
#include "ExtensionClass.h"
#endif
/* ----------------------------------------------------- */
static
void
PyVar_Assign
(
PyObject
**
v
,
PyObject
*
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 OBJECT(O) ((PyObject*)(O))
static
PyObject
*
py___record_schema__
;
/* Declarations for objects of type Record */
typedef
struct
{
#ifdef PERSISTENCE
cPersistent_HEAD
#else
PyObject_HEAD
#endif
PyObject
**
data
;
PyObject
*
schema
;
}
Record
;
staticforward
PyExtensionClass
RecordType
;
/* ---------------------------------------------------------------- */
static
int
Record_init
(
Record
*
self
)
{
int
l
;
UNLESS
(
self
->
schema
)
UNLESS
(
self
->
schema
=
PyObject_GetAttr
(
OBJECT
(
self
->
ob_type
),
py___record_schema__
))
return
-
1
;
if
((
l
=
PyObject_Length
(
self
->
schema
))
<
0
)
return
-
1
;
UNLESS
(
self
->
data
)
{
UNLESS
(
self
->
data
=
malloc
(
sizeof
(
PyObject
*
)
*
(
l
+
1
)))
{
PyErr_NoMemory
();
return
-
1
;
}
memset
(
self
->
data
,
0
,
sizeof
(
PyObject
*
)
*
(
l
+
1
));
}
return
l
;
}
static
PyObject
*
Record___setstate__
(
Record
*
self
,
PyObject
*
args
)
{
PyObject
*
state
=
0
,
*
parent
,
**
d
;
int
l
,
ls
,
i
;
if
((
l
=
Record_init
(
self
))
<
0
)
return
NULL
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"|OO"
,
&
state
,
&
parent
))
return
NULL
;
if
(
state
)
{
if
(
PyDict_Check
(
state
))
{
PyObject
*
k
,
*
v
;
for
(
i
=
0
;
PyDict_Next
(
state
,
&
i
,
&
k
,
&
v
);)
if
(
k
&&
v
&&
PyObject_SetAttr
(
OBJECT
(
self
),
k
,
v
)
<
0
)
PyErr_Clear
();
}
else
{
if
((
ls
=
PyObject_Length
(
state
))
<
0
)
return
NULL
;
for
(
i
=
0
,
d
=
self
->
data
;
i
<
l
&&
i
<
ls
;
i
++
,
d
++
)
{
ASSIGN
(
*
d
,
PySequence_GetItem
(
state
,
i
));
UNLESS
(
*
d
)
return
NULL
;
}
}
}
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyObject
*
Record___getstate__
(
Record
*
self
,
PyObject
*
args
)
{
PyObject
*
r
,
**
d
,
*
v
;
int
i
,
l
;
UNLESS
(
self
->
data
)
return
PyTuple_New
(
0
);
if
((
l
=
Record_init
(
self
))
<
0
)
return
NULL
;
UNLESS
(
r
=
PyTuple_New
(
l
))
return
NULL
;
for
(
d
=
self
->
data
,
i
=
0
;
i
<
l
;
i
++
,
d
++
)
{
v
=
*
d
;
if
(
!
v
)
v
=
Py_None
;
Py_INCREF
(
v
);
PyTuple_SET_ITEM
(
r
,
i
,
v
);
}
return
r
;
}
static
void
Record_deal
(
Record
*
self
)
{
int
l
;
PyObject
**
d
;
if
(
self
->
schema
)
{
l
=
PyObject_Length
(
self
->
schema
);
for
(
d
=
self
->
data
;
--
l
>=
0
;
d
++
)
{
Py_XDECREF
(
*
d
);
}
Py_DECREF
(
self
->
schema
);
free
(
self
->
data
);
}
}
#ifdef PERSISTENCE
static
PyObject
*
Record__p_deactivate
(
Record
*
self
,
PyObject
*
args
)
{
Record_deal
(
self
);
self
->
schema
=
NULL
;
self
->
data
=
NULL
;
self
->
state
=
cPersistent_GHOST_STATE
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
#endif
static
struct
PyMethodDef
Record_methods
[]
=
{
{
"__getstate__"
,
(
PyCFunction
)
Record___getstate__
,
METH_VARARGS
,
"__getstate__() -- Get the record's data"
},
{
"__setstate__"
,
(
PyCFunction
)
Record___setstate__
,
METH_VARARGS
,
"__setstate__(v) -- Set the record's data"
},
{
"__init__"
,
(
PyCFunction
)
Record___setstate__
,
METH_VARARGS
,
"__init__([v]) -- Initialize a record, possibly with state"
},
#ifdef PERSISTENCE
{
"_p_deactivate"
,
(
PyCFunction
)
Record__p_deactivate
,
METH_VARARGS
,
"_p_deactivate() -- Reset the record's data"
},
#endif
{
NULL
,
NULL
}
/* sentinel */
};
/* ---------- */
static
void
Record_dealloc
(
Record
*
self
)
{
Record_deal
(
self
);
Py_DECREF
(
self
->
ob_type
);
PyMem_DEL
(
self
);
}
static
PyObject
*
Record_getattr
(
Record
*
self
,
PyObject
*
name
)
{
int
l
,
i
;
PyObject
*
io
;
if
((
l
=
Record_init
(
self
))
<
0
)
return
NULL
;
if
((
io
=
Py_FindAttr
((
PyObject
*
)
self
,
name
)))
return
io
;
PyErr_Clear
();
if
((
io
=
PyObject_GetItem
(
self
->
schema
,
name
)))
{
UNLESS
(
PyInt_Check
(
io
))
{
PyErr_SetString
(
PyExc_TypeError
,
"invalid record schema"
);
return
NULL
;
}
i
=
PyInt_AsLong
(
io
);
if
(
i
>=
0
&&
i
<
l
)
{
ASSIGN
(
io
,
self
->
data
[
i
]);
UNLESS
(
io
)
io
=
Py_None
;
}
else
ASSIGN
(
io
,
Py_None
);
Py_INCREF
(
io
);
return
io
;
}
PyErr_SetObject
(
PyExc_AttributeError
,
name
);
return
NULL
;
}
static
int
Record_setattr
(
Record
*
self
,
PyObject
*
name
,
PyObject
*
v
)
{
int
l
,
i
;
PyObject
*
io
;
if
((
l
=
Record_init
(
self
))
<
0
)
return
-
1
;
if
((
io
=
PyObject_GetItem
(
self
->
schema
,
name
)))
{
UNLESS
(
PyInt_Check
(
io
))
{
PyErr_SetString
(
PyExc_TypeError
,
"invalid record schema"
);
return
-
1
;
}
i
=
PyInt_AsLong
(
io
);
Py_DECREF
(
io
);
if
(
i
>=
0
&&
i
<
l
)
{
Py_XINCREF
(
v
);
ASSIGN
(
self
->
data
[
i
],
v
);
return
0
;
}
}
PyErr_SetObject
(
PyExc_AttributeError
,
name
);
return
-
1
;
}
#ifdef PERSISTENCE
static
PyObject
*
pRecord_getattr
(
Record
*
self
,
PyObject
*
name
)
{
char
*
c
;
UNLESS
(
c
=
PyString_AsString
(
name
))
return
NULL
;
return
cPersistenceCAPI
->
pergetattro
(
OBJECT
(
self
),
name
,
c
,
Record_getattr
);
}
static
int
pRecord_setattr
(
Record
*
self
,
PyObject
*
name
,
PyObject
*
v
)
{
return
cPersistenceCAPI
->
persetattro
(
OBJECT
(
self
),
name
,
v
,
Record_setattr
);
}
#endif
static
int
Record_compare
(
Record
*
v
,
Record
*
w
)
{
int
lv
,
lw
,
i
,
c
;
PyObject
**
dv
,
**
dw
;
if
((
lv
=
Record_init
(
v
))
<
0
)
return
-
1
;
if
((
lw
=
Record_init
(
w
))
<
0
)
return
-
1
;
if
(
lw
<
lv
)
lv
=
lw
;
for
(
i
=
0
,
dv
=
v
->
data
,
dw
=
w
->
data
;
i
<
lv
;
i
++
,
dv
++
,
dw
++
)
{
if
(
*
dv
)
if
(
*
dw
)
{
if
((
c
=
PyObject_Compare
(
*
dv
,
*
dw
)))
return
c
;
}
else
return
1
;
else
if
(
*
dw
)
return
-
1
;
}
if
(
*
dv
)
return
1
;
if
(
*
dw
)
return
-
1
;
return
0
;
}
/* Code to handle accessing Record objects as sequence objects */
static
PyObject
*
Record_concat
(
Record
*
self
,
PyObject
*
bb
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Record objects do not support concatenation"
);
return
NULL
;
}
static
PyObject
*
Record_repeat
(
Record
*
self
,
int
n
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Record objects do not support repetition"
);
return
NULL
;
}
static
PyObject
*
IndexError
(
int
i
)
{
PyObject
*
v
;
if
((
v
=
PyInt_FromLong
(
i
)))
{
PyErr_SetObject
(
PyExc_IndexError
,
v
);
Py_DECREF
(
v
);
}
return
NULL
;
}
static
PyObject
*
Record_item
(
Record
*
self
,
int
i
)
{
PyObject
*
o
;
int
l
;
if
((
l
=
Record_init
(
self
))
<
0
)
return
NULL
;
if
(
i
<
0
||
i
>=
l
)
return
IndexError
(
i
);
o
=
self
->
data
[
i
];
UNLESS
(
o
)
o
=
Py_None
;
Py_INCREF
(
o
);
return
o
;
}
static
PyObject
*
Record_slice
(
Record
*
self
,
int
ilow
,
int
ihigh
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Record objects do not support slicing"
);
return
NULL
;
}
static
int
Record_ass_item
(
Record
*
self
,
int
i
,
PyObject
*
v
)
{
int
l
;
if
((
l
=
Record_init
(
self
))
<
0
)
return
-
1
;
if
(
i
<
0
||
i
>=
l
)
{
IndexError
(
i
);
return
-
1
;
}
UNLESS
(
v
)
{
PyErr_SetString
(
PyExc_TypeError
,
"cannot delete record items"
);
return
-
1
;
}
Py_INCREF
(
v
);
ASSIGN
(
self
->
data
[
i
],
v
);
return
0
;
}
static
int
Record_ass_slice
(
Record
*
self
,
int
ilow
,
int
ihigh
,
PyObject
*
v
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Record objects do not support slice assignment"
);
return
-
1
;
}
static
PySequenceMethods
Record_as_sequence
=
{
(
inquiry
)
Record_init
,
/*sq_length*/
(
binaryfunc
)
Record_concat
,
/*sq_concat*/
(
intargfunc
)
Record_repeat
,
/*sq_repeat*/
(
intargfunc
)
Record_item
,
/*sq_item*/
(
intintargfunc
)
Record_slice
,
/*sq_slice*/
(
intobjargproc
)
Record_ass_item
,
/*sq_ass_item*/
(
intintobjargproc
)
Record_ass_slice
,
/*sq_ass_slice*/
};
/* -------------------------------------------------------------- */
static
PyObject
*
Record_subscript
(
Record
*
self
,
PyObject
*
key
)
{
int
i
,
l
;
PyObject
*
io
;
if
((
l
=
Record_init
(
self
))
<
0
)
return
NULL
;
if
(
PyInt_Check
(
key
))
{
i
=
PyInt_AsLong
(
key
);
if
(
i
<
0
)
i
+=
l
;
return
Record_item
(
self
,
i
);
}
if
((
io
=
PyObject_GetItem
(
self
->
schema
,
key
)))
{
UNLESS
(
PyInt_Check
(
io
))
{
PyErr_SetString
(
PyExc_TypeError
,
"invalid record schema"
);
return
NULL
;
}
i
=
PyInt_AsLong
(
io
);
if
(
i
>=
0
&&
i
<
l
)
{
ASSIGN
(
io
,
self
->
data
[
i
]);
UNLESS
(
io
)
io
=
Py_None
;
}
else
ASSIGN
(
io
,
Py_None
);
Py_INCREF
(
io
);
return
io
;
}
PyErr_Clear
();
if
((
io
=
PyObject_GetAttr
(
OBJECT
(
self
),
key
)))
return
io
;
PyErr_SetObject
(
PyExc_KeyError
,
key
);
return
NULL
;
}
static
int
Record_ass_sub
(
Record
*
self
,
PyObject
*
key
,
PyObject
*
v
)
{
int
i
,
l
;
PyObject
*
io
;
if
((
l
=
Record_init
(
self
))
<
0
)
return
-
1
;
if
(
PyInt_Check
(
key
))
{
i
=
PyInt_AsLong
(
key
);
if
(
i
<
0
)
i
+=
l
;
return
Record_ass_item
(
self
,
i
,
v
);
}
if
((
io
=
PyObject_GetItem
(
self
->
schema
,
key
)))
{
UNLESS
(
PyInt_Check
(
io
))
{
PyErr_SetString
(
PyExc_TypeError
,
"invalid record schema"
);
return
-
1
;
}
i
=
PyInt_AsLong
(
io
);
Py_DECREF
(
io
);
if
(
i
>=
0
&&
i
<
l
)
{
Py_XINCREF
(
v
);
ASSIGN
(
self
->
data
[
i
],
v
);
return
0
;
}
}
return
-
1
;
}
static
PyMappingMethods
Record_as_mapping
=
{
(
inquiry
)
Record_init
,
/*mp_length*/
(
binaryfunc
)
Record_subscript
,
/*mp_subscript*/
(
objobjargproc
)
Record_ass_sub
,
/*mp_ass_subscript*/
};
/* -------------------------------------------------------- */
static
PyExtensionClass
RecordType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"Record"
,
/*tp_name*/
sizeof
(
Record
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
Record_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
0
,
/*obsolete tp_getattr*/
(
setattrfunc
)
0
,
/*obsolete tp_setattr*/
(
cmpfunc
)
Record_compare
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
&
Record_as_sequence
,
/*tp_as_sequence*/
&
Record_as_mapping
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
0
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
#ifdef PERSISTENCE
(
getattrofunc
)
pRecord_getattr
,
/*tp_getattro*/
(
setattrofunc
)
pRecord_setattr
,
/*tp_setattro*/
#else
(
getattrofunc
)
Record_getattr
,
/*tp_getattro*/
(
setattrofunc
)
Record_setattr
,
/*tp_setattro*/
#endif
/* Space for future expansion */
0L
,
0L
,
"Simple Record Types"
,
/* Documentation string */
METHOD_CHAIN
(
Record_methods
),
EXTENSIONCLASS_NOINSTDICT_FLAG
,
};
/* End of code for Record objects */
/* -------------------------------------------------------- */
/* List of methods defined in the module */
static
struct
PyMethodDef
Module_Level__methods
[]
=
{
{
NULL
,
(
PyCFunction
)
NULL
,
0
,
NULL
}
/* sentinel */
};
/* Initialization function for the module (*must* be called initRecord) */
void
initRecord
()
{
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.10 $"
;
UNLESS
(
py___record_schema__
=
PyString_FromString
(
"__record_schema__"
))
return
;
UNLESS
(
ExtensionClassImported
)
return
;
#ifdef PERSISTENCE
if
(
cPersistenceCAPI
=
PyCObject_Import
(
"cPersistence"
,
"CAPI"
))
{
static
PyMethodChain
m
;
m
.
methods
=
RecordType
.
methods
.
methods
;
RecordType
.
methods
.
methods
=
cPersistenceCAPI
->
methods
->
methods
;
RecordType
.
methods
.
link
=&
m
;
}
else
return
;
#endif
/* Create the module and add the functions */
m
=
Py_InitModule4
(
"Record"
,
Module_Level__methods
,
Record_module_documentation
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
/* Add some symbolic constants to the module */
d
=
PyModule_GetDict
(
m
);
PyExtensionClass_Export
(
d
,
"Record"
,
RecordType
);
PyDict_SetItemString
(
d
,
"__version__"
,
PyString_FromStringAndSize
(
rev
+
11
,
strlen
(
rev
+
11
)
-
2
));
/* Check for errors */
if
(
PyErr_Occurred
())
Py_FatalError
(
"can't initialize module Record"
);
}
/*****************************************************************************
Revision Log:
$Log: Record.c,v $
Revision 1.10 2001/02/19 19:16:07 jeremy
silence compiler warnings
(2 remain)
Revision 1.9 2000/04/21 14:17:23 tseaver
Collector #1012: Guarantee null-terminated buffer in Record_init() so Record_compare doesn't UMR
Revision 1.8.6.1 2000/04/11 20:39:17 tseaver
Guarantee null-terminated buffer in Record_init() so Record_compare doesn't UMR
Revision 1.8 1999/06/10 20:11:53 jim
Updated to use new ExtensionClass destructor protocol.
Revision 1.7 1999/04/16 15:21:40 jim
Added logic to fall back to getattr when getitem fails.
This is needed to make computed attributes work in ZTables,
but it might be better to expand the schema notion to accomidate
computed attributes.
Revision 1.6 1999/03/10 00:14:41 klm
Committing with version 1.0 of the license.
Revision 1.5 1998/12/04 20:15:24 jim
Detabification and new copyright.
Revision 1.4 1998/07/27 13:09:58 jim
Changed _p___reinit__ to _p_deactivate.
Revision 1.3 1998/01/16 21:13:28 jim
Added extra ignored parent object argument to __init__ and
__setstate__.
Revision 1.2 1997/09/26 15:05:17 jim
Added sequence and mapping behavior.
Revision 1.1 1997/09/25 22:12:28 jim
*** empty log message ***
Revision 1.5 1997/07/16 20:17:45 jim
*** empty log message ***
Revision 1.4 1997/06/06 18:31:54 jim
Fixed bug in __getstate__ that caused core dumps when some attributes
were unset.
Revision 1.3 1997/05/19 14:05:46 jim
Fixed several bugs.
Revision 1.2 1997/04/30 11:37:35 jim
Fixed bug in reinitialization that probably explains the bug that
Ellen reported where ad attributes were set to None.
Revision 1.1 1997/04/27 09:18:42 jim
*** empty log message ***
$Revision 1.1 1997/02/24 23:25:42 jim
$initial
$
*****************************************************************************/
lib/Components/ExtensionClass/Sync.c
deleted
100644 → 0
View file @
7dbb8830
/*
Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
o Redistributions of source code must retain the above copyright
notice, this list of conditions, and the disclaimer that follows.
o Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
o Neither the name of Digital Creations nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
$Id: Sync.c,v 1.2 1998/11/17 20:22:34 jim Exp $
If you have questions regarding this software,
contact:
Digital Creations L.C.
info@digicool.com
(540) 371-6909
*/
static
char
Sync_module_documentation
[]
=
""
"
\n
$Id: Sync.c,v 1.2 1998/11/17 20:22:34 jim Exp $"
;
#include "ExtensionClass.h"
static
PyObject
*
ErrorObject
;
/* ----------------------------------------------------- */
static
void
PyVar_Assign
(
PyObject
**
v
,
PyObject
*
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 OBJECT(O) ((PyObject*)(O))
PyObject
*
lockstr
,
*
aqstr
,
*
restr
,
*
newlock
;
static
PyObject
*
Synchronized___call_method__
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
f
,
*
a
,
*
k
=
0
,
*
l
=
0
,
*
aq
=
0
,
*
t
,
*
v
,
*
tb
,
*
r
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"OO|O"
,
&
f
,
&
a
,
&
k
))
return
NULL
;
UNLESS
(
l
=
PyObject_GetAttr
(
self
,
lockstr
))
{
PyErr_Clear
();
UNLESS
(
l
=
PyObject_CallObject
(
newlock
,
NULL
))
return
NULL
;
if
(
PyObject_SetAttr
(
self
,
lockstr
,
l
)
<
0
)
goto
err
;
}
UNLESS
(
aq
=
PyObject_GetAttr
(
l
,
aqstr
))
goto
err
;
UNLESS_ASSIGN
(
aq
,
PyObject_CallObject
(
aq
,
NULL
))
goto
err
;
if
(
k
)
r
=
PyEval_CallObjectWithKeywords
(
f
,
a
,
k
);
else
r
=
PyObject_CallObject
(
f
,
a
);
PyErr_Fetch
(
&
t
,
&
v
,
&
tb
);
ASSIGN
(
aq
,
PyObject_GetAttr
(
l
,
restr
));
if
(
aq
)
ASSIGN
(
aq
,
PyObject_CallObject
(
aq
,
NULL
));
Py_XDECREF
(
aq
);
Py_DECREF
(
l
);
PyErr_Restore
(
t
,
v
,
tb
);
return
r
;
err:
Py_DECREF
(
l
);
return
NULL
;
}
static
struct
PyMethodDef
Synchronized_methods
[]
=
{
{
"__call_method__"
,
(
PyCFunction
)
Synchronized___call_method__
,
METH_VARARGS
,
"Call a method by first getting a thread lock"
},
{
NULL
,
NULL
}
};
static
struct
PyMethodDef
Module_Level__methods
[]
=
{
{
NULL
,
(
PyCFunction
)
NULL
,
0
,
NULL
}
};
void
initSync
()
{
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.2 $"
;
PURE_MIXIN_CLASS
(
Synchronized
,
"Mix-in class that provides synchonization of method calls
\n
"
"
\n
"
"Only one thread is allowed to call a synchronized
\n
"
"object's methods.
\n
"
,
Synchronized_methods
);
UNLESS
((
lockstr
=
PyString_FromString
(
"_sync__lock"
))
&&
(
aqstr
=
PyString_FromString
(
"acquire"
))
&&
(
restr
=
PyString_FromString
(
"release"
))
&&
(
newlock
=
PyImport_ImportModule
(
"ThreadLock"
))
)
return
;
ASSIGN
(
newlock
,
PyObject_GetAttrString
(
newlock
,
"allocate_lock"
));
UNLESS
(
newlock
)
return
;
m
=
Py_InitModule4
(
"Sync"
,
Module_Level__methods
,
Sync_module_documentation
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
d
=
PyModule_GetDict
(
m
);
PyExtensionClass_Export
(
d
,
"Synchronized"
,
SynchronizedType
);
PyDict_SetItemString
(
d
,
"__version__"
,
PyString_FromStringAndSize
(
rev
+
11
,
strlen
(
rev
+
11
)
-
2
));
CHECK_FOR_ERRORS
(
"can't initialize module MethodObject"
);
}
lib/Components/ExtensionClass/ThreadLock.c
deleted
100644 → 0
View file @
7dbb8830
/*
Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
o Redistributions of source code must retain the above copyright
notice, this list of conditions, and the disclaimer that follows.
o Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
o Neither the name of Digital Creations nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
$Id: ThreadLock.c,v 1.7 1999/02/19 16:10:05 jim Exp $
If you have questions regarding this software,
contact:
Digital Creations L.C.
info@digicool.com
(540) 371-6909
*/
static
char
ThreadLock_module_documentation
[]
=
""
"
\n
$Id: ThreadLock.c,v 1.7 1999/02/19 16:10:05 jim Exp $"
;
#include "Python.h"
#ifdef WITH_THREAD
#include "listobject.h"
#ifdef PyList_SET_ITEM
#include "pythread.h"
#define get_thread_ident PyThread_get_thread_ident
#define acquire_lock PyThread_acquire_lock
#define release_lock PyThread_release_lock
#define type_lock PyThread_type_lock
#define free_lock PyThread_free_lock
#define allocate_lock PyThread_allocate_lock
#else
#include "thread.h"
#endif
#endif
static
PyObject
*
ErrorObject
;
/* ----------------------------------------------------- */
#define UNLESS(E) if(!(E))
/* Declarations for objects of type ThreadLock */
typedef
struct
{
PyObject_HEAD
int
count
;
long
id
;
#ifdef WITH_THREAD
type_lock
lock
;
#endif
}
ThreadLockObject
;
staticforward
PyTypeObject
ThreadLockType
;
static
int
cacquire
(
ThreadLockObject
*
self
)
{
#ifdef WITH_THREAD
long
id
=
get_thread_ident
();
#else
long
id
=
1
;
#endif
if
(
self
->
count
>=
0
&&
self
->
id
==
id
)
{
/* Somebody has locked me. It is either the current thread or
another thread. */
/* So this thread has it. I can't have a race condition, because,
if another thread had the lock, then the id would not be this
one. */
self
->
count
++
;
}
else
{
#ifdef WITH_THREAD
Py_BEGIN_ALLOW_THREADS
acquire_lock
(
self
->
lock
,
1
);
Py_END_ALLOW_THREADS
#endif
self
->
count
=
0
;
self
->
id
=
id
;
}
return
0
;
}
static
PyObject
*
acquire
(
ThreadLockObject
*
self
,
PyObject
*
args
)
{
if
(
cacquire
(
self
)
<
0
)
return
NULL
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
int
crelease
(
ThreadLockObject
*
self
)
{
#ifdef WITH_THREAD
long
id
=
get_thread_ident
();
#else
long
id
=
1
;
#endif
if
(
self
->
count
>=
0
&&
self
->
id
==
id
)
{
/* Somebody has locked me. It is either the current thread or
another thread. */
/* So this thread has it. I can't have a race condition, because,
if another thread had the lock, then the id would not be this
one. */
self
->
count
--
;
#ifdef WITH_THREAD
if
(
self
->
count
<
0
)
release_lock
(
self
->
lock
);
#endif
}
else
{
PyErr_SetString
(
ErrorObject
,
"release unlocked lock"
);
return
-
1
;
}
return
0
;
}
static
PyObject
*
release
(
ThreadLockObject
*
self
,
PyObject
*
args
)
{
if
(
crelease
(
self
)
<
0
)
return
NULL
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyObject
*
call_method
(
ThreadLockObject
*
self
,
PyObject
*
args
)
{
PyObject
*
f
,
*
a
=
0
,
*
k
=
0
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"OO|O"
,
&
f
,
&
a
,
&
k
))
return
NULL
;
if
(
cacquire
(
self
)
<
0
)
return
NULL
;
f
=
PyEval_CallObjectWithKeywords
(
f
,
a
,
k
);
if
(
crelease
(
self
)
<
0
)
{
Py_XDECREF
(
f
);
f
=
NULL
;
}
return
f
;
}
static
struct
PyMethodDef
ThreadLock_methods
[]
=
{
{
"guarded_apply"
,
(
PyCFunction
)
call_method
,
1
,
"guarded_apply(FUNCTION, ARGS[, KEYWORDS]) -- Make a guarded function call
\n
"
"
\n
"
"Acquire the lock, call the function, and then release the lock.
\n
"
},
{
"acquire"
,
(
PyCFunction
)
acquire
,
1
,
"acquire() -- Acquire a lock, taking the thread ID into account"
},
{
"release"
,
(
PyCFunction
)
release
,
1
,
"release() -- Release a lock, taking the thread ID into account"
},
{
NULL
,
NULL
}
/* sentinel */
};
static
void
ThreadLock_dealloc
(
ThreadLockObject
*
self
)
{
#ifdef WITH_THREAD
free_lock
(
self
->
lock
);
#endif
PyMem_DEL
(
self
);
}
static
PyObject
*
ThreadLock_getattr
(
ThreadLockObject
*
self
,
PyObject
*
name
)
{
char
*
cname
;
if
((
cname
=
PyString_AsString
(
name
)))
{
if
(
*
cname
==
'c'
&&
strcmp
(
cname
,
"count"
)
==
0
)
return
PyInt_FromLong
(
self
->
count
);
if
(
*
cname
==
'i'
&&
strcmp
(
cname
,
"id"
)
==
0
)
return
PyInt_FromLong
(
self
->
id
);
return
Py_FindMethod
(
ThreadLock_methods
,
(
PyObject
*
)
self
,
cname
);
}
PyErr_SetObject
(
PyExc_AttributeError
,
name
);
return
NULL
;
}
static
PyTypeObject
ThreadLockType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"ThreadLock"
,
/*tp_name*/
sizeof
(
ThreadLockObject
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
ThreadLock_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
0
,
/*obsolete tp_getattr*/
(
setattrfunc
)
0
,
/*obsolete 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*/
(
getattrofunc
)
ThreadLock_getattr
,
/*tp_getattro*/
0
,
/*tp_setattro*/
/* Space for future expansion */
0L
,
0L
,
"Thread-based lock objects
\n
"
"
\n
"
"These lock objects may be allocated multiple times by the same
\n
"
"thread, but may only be allocated by one thread at a time.
\n
"
"This is useful for locking instances in possibly nested method calls
\n
"
};
static
PyObject
*
newThreadLockObject
(
ThreadLockObject
*
self
,
PyObject
*
args
)
{
UNLESS
(
PyArg_ParseTuple
(
args
,
""
))
return
NULL
;
UNLESS
(
self
=
PyObject_NEW
(
ThreadLockObject
,
&
ThreadLockType
))
return
NULL
;
self
->
count
=-
1
;
#ifdef WITH_THREAD
self
->
lock
=
allocate_lock
();
if
(
self
->
lock
==
NULL
)
{
PyMem_DEL
(
self
);
self
=
NULL
;
PyErr_SetString
(
ErrorObject
,
"can't allocate lock"
);
}
#endif
return
(
PyObject
*
)
self
;
}
static
PyObject
*
ident
(
PyObject
*
self
,
PyObject
*
args
)
{
#ifdef WITH_THREAD
return
PyInt_FromLong
(
get_thread_ident
());
#else
return
PyInt_FromLong
(
0
);
#endif
}
static
struct
PyMethodDef
Module_methods
[]
=
{
{
"allocate_lock"
,
(
PyCFunction
)
newThreadLockObject
,
1
,
"allocate_lock() -- Return a new lock object"
},
{
"get_ident"
,
(
PyCFunction
)
ident
,
1
,
"get_ident() -- Get the id of the current thread"
},
{
NULL
,
(
PyCFunction
)
NULL
,
0
,
NULL
}
/* sentinel */
};
void
initThreadLock
()
{
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.7 $"
;
m
=
Py_InitModule4
(
"ThreadLock"
,
Module_methods
,
ThreadLock_module_documentation
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
d
=
PyModule_GetDict
(
m
);
ThreadLockType
.
ob_type
=&
PyType_Type
;
PyDict_SetItemString
(
d
,
"ThreadLockType"
,
(
PyObject
*
)
&
ThreadLockType
);
ErrorObject
=
PyString_FromString
(
"ThreadLock.error"
);
PyDict_SetItemString
(
d
,
"error"
,
ErrorObject
);
PyDict_SetItemString
(
d
,
"__version__"
,
PyString_FromStringAndSize
(
rev
+
11
,
strlen
(
rev
+
11
)
-
2
));
#ifdef WITH_THREAD
PyDict_SetItemString
(
d
,
"WITH_THREAD"
,
PyInt_FromLong
(
1
));
#else
PyDict_SetItemString
(
d
,
"WITH_THREAD"
,
Py_None
);
#endif
/* Check for errors */
if
(
PyErr_Occurred
())
Py_FatalError
(
"can't initialize module ThreadLock"
);
}
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