mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-30 13:24:27 +01:00
pure.c: custom getsetters
This commit is contained in:
@@ -55,7 +55,7 @@ static PyMethodDef my_native_methods[] = {
|
|||||||
* self.number = number
|
* self.number = number
|
||||||
*
|
*
|
||||||
* def name(self):
|
* def name(self):
|
||||||
* return '{} {}'.format(self.first, self.last)
|
* return '{} {} {}'.format(self.first, self.last, self.number)
|
||||||
*
|
*
|
||||||
* class MyDerivedNativeClass(MyNativeClass):
|
* class MyDerivedNativeClass(MyNativeClass):
|
||||||
*
|
*
|
||||||
@@ -66,7 +66,7 @@ static PyMethodDef my_native_methods[] = {
|
|||||||
* self.number2 = number2
|
* self.number2 = number2
|
||||||
*
|
*
|
||||||
* def name(self):
|
* def name(self):
|
||||||
* return '{} {} {} {} 2'.format(self.first, self.last, self.first2, self.last2)
|
* return '{} {} {} {} {} {}'.format(self.first, self.last, self.number + 1, self.first2, self.last2, self.number2 + 2)
|
||||||
* ....
|
* ....
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -147,15 +147,69 @@ my_native_module_MyNativeClass_init(my_native_module_MyNativeClass *self, PyObje
|
|||||||
}
|
}
|
||||||
|
|
||||||
static PyMemberDef my_native_module_MyNativeClass_members[] = {
|
static PyMemberDef my_native_module_MyNativeClass_members[] = {
|
||||||
{"first", T_OBJECT_EX, offsetof(my_native_module_MyNativeClass, first), 0,
|
|
||||||
"first name"},
|
|
||||||
{"last", T_OBJECT_EX, offsetof(my_native_module_MyNativeClass, last), 0,
|
|
||||||
"last name"},
|
|
||||||
{"number", T_INT, offsetof(my_native_module_MyNativeClass, number), 0,
|
{"number", T_INT, offsetof(my_native_module_MyNativeClass, number), 0,
|
||||||
"custom number"},
|
"custom number"},
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
my_native_module_MyNativeClass_getfirst(my_native_module_MyNativeClass *self, void *closure)
|
||||||
|
{
|
||||||
|
(void)closure;
|
||||||
|
Py_INCREF(self->first);
|
||||||
|
return self->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
my_native_module_MyNativeClass_setfirst(my_native_module_MyNativeClass *self, PyObject *value, void *closure)
|
||||||
|
{
|
||||||
|
(void)closure;
|
||||||
|
PyObject *tmp;
|
||||||
|
if (value == NULL) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!PyUnicode_Check(value)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"The first attribute value must be a string");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tmp = self->first;
|
||||||
|
Py_INCREF(value);
|
||||||
|
self->first = value;
|
||||||
|
Py_DECREF(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
my_native_module_MyNativeClass_getlast(my_native_module_MyNativeClass *self, void *closure)
|
||||||
|
{
|
||||||
|
(void)closure;
|
||||||
|
Py_INCREF(self->last);
|
||||||
|
return self->last;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
my_native_module_MyNativeClass_setlast(my_native_module_MyNativeClass *self, PyObject *value, void *closure)
|
||||||
|
{
|
||||||
|
(void)closure;
|
||||||
|
PyObject *tmp;
|
||||||
|
if (value == NULL) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!PyUnicode_Check(value)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"The last attribute value must be a string");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tmp = self->last;
|
||||||
|
Py_INCREF(value);
|
||||||
|
self->last = value;
|
||||||
|
Py_DECREF(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
my_native_module_MyNativeClass_name(my_native_module_MyNativeClass *self, PyObject *Py_UNUSED(ignored))
|
my_native_module_MyNativeClass_name(my_native_module_MyNativeClass *self, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
@@ -167,9 +221,17 @@ my_native_module_MyNativeClass_name(my_native_module_MyNativeClass *self, PyObje
|
|||||||
PyErr_SetString(PyExc_AttributeError, "last");
|
PyErr_SetString(PyExc_AttributeError, "last");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return PyUnicode_FromFormat("%S %S", self->first, self->last);
|
return PyUnicode_FromFormat("%S %S %d", self->first, self->last, self->number + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyGetSetDef my_native_module_MyNativeClass_getsetters[] = {
|
||||||
|
{"first", (getter) my_native_module_MyNativeClass_getfirst, (setter) my_native_module_MyNativeClass_setfirst,
|
||||||
|
"first name", NULL},
|
||||||
|
{"last", (getter) my_native_module_MyNativeClass_getlast, (setter) my_native_module_MyNativeClass_setlast,
|
||||||
|
"last name", NULL},
|
||||||
|
{NULL} /* Sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
static PyMethodDef my_native_module_MyNativeClass_methods[] = {
|
static PyMethodDef my_native_module_MyNativeClass_methods[] = {
|
||||||
{
|
{
|
||||||
"name",
|
"name",
|
||||||
@@ -194,6 +256,7 @@ static PyTypeObject my_native_module_MyNativeClassType = {
|
|||||||
.tp_clear = (inquiry) my_native_module_MyNativeClass_clear,
|
.tp_clear = (inquiry) my_native_module_MyNativeClass_clear,
|
||||||
.tp_members = my_native_module_MyNativeClass_members,
|
.tp_members = my_native_module_MyNativeClass_members,
|
||||||
.tp_methods = my_native_module_MyNativeClass_methods,
|
.tp_methods = my_native_module_MyNativeClass_methods,
|
||||||
|
.tp_getset = my_native_module_MyNativeClass_getsetters,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -232,7 +295,7 @@ my_native_module_MyDerivedNativeClass_new(PyTypeObject *type, PyObject *args, Py
|
|||||||
(void)args;
|
(void)args;
|
||||||
(void)kwds;
|
(void)kwds;
|
||||||
my_native_module_MyDerivedNativeClass *self;
|
my_native_module_MyDerivedNativeClass *self;
|
||||||
self = (my_native_module_MyDerivedNativeClass *) type->tp_alloc(type, 0);
|
self = (my_native_module_MyDerivedNativeClass *) type->tp_base->tp_new(type, args, kwds);
|
||||||
if (self != NULL) {
|
if (self != NULL) {
|
||||||
self->first2 = PyUnicode_FromString("");
|
self->first2 = PyUnicode_FromString("");
|
||||||
if (self->first2 == NULL) {
|
if (self->first2 == NULL) {
|
||||||
@@ -281,20 +344,74 @@ my_native_module_MyDerivedNativeClass_init(my_native_module_MyDerivedNativeClass
|
|||||||
}
|
}
|
||||||
|
|
||||||
static PyMemberDef my_native_module_MyDerivedNativeClass_members[] = {
|
static PyMemberDef my_native_module_MyDerivedNativeClass_members[] = {
|
||||||
{"first2", T_OBJECT_EX, offsetof(my_native_module_MyDerivedNativeClass, first2), 0,
|
|
||||||
"first2 name2"},
|
|
||||||
{"last2", T_OBJECT_EX, offsetof(my_native_module_MyDerivedNativeClass, last2), 0,
|
|
||||||
"last2 name2"},
|
|
||||||
{"number2", T_INT, offsetof(my_native_module_MyDerivedNativeClass, number2), 0,
|
{"number2", T_INT, offsetof(my_native_module_MyDerivedNativeClass, number2), 0,
|
||||||
"custom number2"},
|
"custom number2"},
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
my_native_module_MyDerivedNativeClass_getfirst2(my_native_module_MyDerivedNativeClass *self, void *closure)
|
||||||
|
{
|
||||||
|
(void)closure;
|
||||||
|
Py_INCREF(self->first2);
|
||||||
|
return self->first2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
my_native_module_MyDerivedNativeClass_setfirst2(my_native_module_MyDerivedNativeClass *self, PyObject *value, void *closure)
|
||||||
|
{
|
||||||
|
(void)closure;
|
||||||
|
PyObject *tmp;
|
||||||
|
if (value == NULL) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Cannot delete the first2 attribute");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!PyUnicode_Check(value)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"The first2 attribute value must be a string");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tmp = self->first2;
|
||||||
|
Py_INCREF(value);
|
||||||
|
self->first2 = value;
|
||||||
|
Py_DECREF(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
my_native_module_MyDerivedNativeClass_getlast2(my_native_module_MyDerivedNativeClass *self, void *closure)
|
||||||
|
{
|
||||||
|
(void)closure;
|
||||||
|
Py_INCREF(self->last2);
|
||||||
|
return self->last2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
my_native_module_MyDerivedNativeClass_setlast2(my_native_module_MyDerivedNativeClass *self, PyObject *value, void *closure)
|
||||||
|
{
|
||||||
|
(void)closure;
|
||||||
|
PyObject *tmp;
|
||||||
|
if (value == NULL) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Cannot delete the last2 attribute");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!PyUnicode_Check(value)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"The last2 attribute value must be a string");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tmp = self->last2;
|
||||||
|
Py_INCREF(value);
|
||||||
|
self->last2 = value;
|
||||||
|
Py_DECREF(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
my_native_module_MyDerivedNativeClass_name2(my_native_module_MyDerivedNativeClass *self, PyObject *Py_UNUSED(ignored))
|
my_native_module_MyDerivedNativeClass_name2(my_native_module_MyDerivedNativeClass *self, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
if (self->base.first == NULL) {
|
if (self->base.first == NULL) {
|
||||||
PyErr_SetString(PyExc_AttributeError, "first");
|
PyErr_SetString(PyExc_AttributeError, "first2");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (self->base.last == NULL) {
|
if (self->base.last == NULL) {
|
||||||
@@ -302,17 +419,26 @@ my_native_module_MyDerivedNativeClass_name2(my_native_module_MyDerivedNativeClas
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (self->first2 == NULL) {
|
if (self->first2 == NULL) {
|
||||||
PyErr_SetString(PyExc_AttributeError, "first2");
|
PyErr_SetString(PyExc_AttributeError, "first22");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (self->last2 == NULL) {
|
if (self->last2 == NULL) {
|
||||||
PyErr_SetString(PyExc_AttributeError, "last2");
|
PyErr_SetString(PyExc_AttributeError, "last2");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return PyUnicode_FromFormat("%S %S %S %S",
|
return PyUnicode_FromFormat("%S %S %d %S %S %d",
|
||||||
self->base.first, self->base.last, self->first2, self->last2);
|
self->base.first, self->base.last, self->base.number + 1,
|
||||||
|
self->first2, self->last2, self->number2 + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyGetSetDef my_native_module_MyDerivedNativeClass_getsetters[] = {
|
||||||
|
{"first2", (getter) my_native_module_MyDerivedNativeClass_getfirst2, (setter) my_native_module_MyDerivedNativeClass_setfirst2,
|
||||||
|
"first2 name", NULL},
|
||||||
|
{"last2", (getter) my_native_module_MyDerivedNativeClass_getlast2, (setter) my_native_module_MyDerivedNativeClass_setlast2,
|
||||||
|
"last2 name", NULL},
|
||||||
|
{NULL} /* Sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
static PyMethodDef my_native_module_MyDerivedNativeClass_methods[] = {
|
static PyMethodDef my_native_module_MyDerivedNativeClass_methods[] = {
|
||||||
{
|
{
|
||||||
"name2",
|
"name2",
|
||||||
@@ -337,6 +463,7 @@ static PyTypeObject my_native_module_MyDerivedNativeClassType = {
|
|||||||
.tp_clear = (inquiry) my_native_module_MyDerivedNativeClass_clear,
|
.tp_clear = (inquiry) my_native_module_MyDerivedNativeClass_clear,
|
||||||
.tp_members = my_native_module_MyDerivedNativeClass_members,
|
.tp_members = my_native_module_MyDerivedNativeClass_members,
|
||||||
.tp_methods = my_native_module_MyDerivedNativeClass_methods,
|
.tp_methods = my_native_module_MyDerivedNativeClass_methods,
|
||||||
|
.tp_getset = my_native_module_MyDerivedNativeClass_getsetters,
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyModuleDef my_native_module = {
|
static PyModuleDef my_native_module = {
|
||||||
|
|||||||
@@ -12,18 +12,18 @@ def test_native_method(a, b):
|
|||||||
def test_native_class():
|
def test_native_class():
|
||||||
# Positional arguments.
|
# Positional arguments.
|
||||||
my_native_object = my_native_module.MyNativeClass('ab', 'cd', 13)
|
my_native_object = my_native_module.MyNativeClass('ab', 'cd', 13)
|
||||||
assert my_native_object.name() == 'ab cd'
|
assert my_native_object.name() == 'ab cd 14'
|
||||||
|
|
||||||
# Named arguments.
|
# Named arguments.
|
||||||
my_native_object = my_native_module.MyNativeClass(first='ef', last='gh', number=13)
|
my_native_object = my_native_module.MyNativeClass(first='ef', last='gh', number=13)
|
||||||
assert my_native_object.name() == 'ef gh'
|
assert my_native_object.name() == 'ef gh 14'
|
||||||
|
|
||||||
# Default values and set property.
|
# Default values and set property.
|
||||||
my_native_object = my_native_module.MyNativeClass()
|
my_native_object = my_native_module.MyNativeClass()
|
||||||
my_native_object.first = 'ih'
|
my_native_object.first = 'ih'
|
||||||
assert my_native_object.name() == 'ih '
|
assert my_native_object.name() == 'ih 1'
|
||||||
|
|
||||||
my_derived_native_object = my_native_module.MyDerivedNativeClass('ab', 'cd', 13, 'ef', 'gh', 21)
|
my_derived_native_object = my_native_module.MyDerivedNativeClass('ab', 'cd', 13, 'ef', 'gh', 21)
|
||||||
assert my_derived_native_object.name() == 'ab cd'
|
assert my_derived_native_object.name() == 'ab cd 14'
|
||||||
assert my_derived_native_object.name2() == 'ab cd ef gh'
|
assert my_derived_native_object.name2() == 'ab cd 14 ef gh 23'
|
||||||
return 13
|
return 13
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include "structmember.h"
|
#include "structmember.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
/* Define a function in C to be accessible from the Python code.
|
/* Define a function in C to be accessible from the Python code.
|
||||||
*
|
*
|
||||||
* ....
|
* ....
|
||||||
@@ -33,32 +35,46 @@ static PyMethodDef my_native_methods[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Define a class in C to be accessible from the Python code.
|
/* Define a class in C to be accessible from the Python code.
|
||||||
*
|
* and bind data and methods it to a C++ class!
|
||||||
* AKA how to write 20 lines of Python in 200 lines of C.
|
|
||||||
*
|
|
||||||
* ....
|
|
||||||
* class MyNativeClass:
|
|
||||||
*
|
|
||||||
* def __init__(self, first='', last='', number=0):
|
|
||||||
* self.first = first
|
|
||||||
* self.last = last
|
|
||||||
* self.number = number
|
|
||||||
*
|
|
||||||
* def name(self):
|
|
||||||
* return '{} {}'.format(self.first, self.last)
|
|
||||||
*
|
|
||||||
* class MyDerivedNativeClass(MyNativeClass):
|
|
||||||
*
|
|
||||||
* def __init__(self, first='', last='', number=0, first2='', last2='', number2=0):
|
|
||||||
* super().__init__(first, last, number, number)
|
|
||||||
* self.first2 = first2
|
|
||||||
* self.last2 = last2
|
|
||||||
* self.number2 = number2
|
|
||||||
*
|
|
||||||
* def name(self):
|
|
||||||
* return '{} {} {} {} 2'.format(self.first, self.last, self.first2, self.last2)
|
|
||||||
* ....
|
* ....
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct MyNativeClass {
|
||||||
|
std::string first;
|
||||||
|
std::string last;
|
||||||
|
int number;
|
||||||
|
|
||||||
|
MyNativeClass(
|
||||||
|
const std::string& first,
|
||||||
|
const std::string& last,
|
||||||
|
int number
|
||||||
|
) : first(first), last(last), number(number) {}
|
||||||
|
|
||||||
|
std::string name() {
|
||||||
|
return first + " " + last;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MyDerivedNativeClass : public MyNativeClass {
|
||||||
|
std::string first2;
|
||||||
|
std::string last2;
|
||||||
|
int number2;
|
||||||
|
|
||||||
|
MyDerivedNativeClass(
|
||||||
|
const std::string& first,
|
||||||
|
const std::string& last,
|
||||||
|
int number,
|
||||||
|
const std::string& first2,
|
||||||
|
const std::string& last2,
|
||||||
|
int number2
|
||||||
|
) : MyNativeClass(first, last, number),
|
||||||
|
first2(first2), last2(last2), number2(number2) {}
|
||||||
|
|
||||||
|
std::string name() {
|
||||||
|
return first + " " + last + " " + first2 + " " + last2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
PyObject *first;
|
PyObject *first;
|
||||||
@@ -137,15 +153,69 @@ my_native_module_MyNativeClass_init(my_native_module_MyNativeClass *self, PyObje
|
|||||||
}
|
}
|
||||||
|
|
||||||
static PyMemberDef my_native_module_MyNativeClass_members[] = {
|
static PyMemberDef my_native_module_MyNativeClass_members[] = {
|
||||||
{(char*)"first", T_OBJECT_EX, offsetof(my_native_module_MyNativeClass, first), 0,
|
|
||||||
(char*)"first name"},
|
|
||||||
{(char*)"last", T_OBJECT_EX, offsetof(my_native_module_MyNativeClass, last), 0,
|
|
||||||
(char*)"last name"},
|
|
||||||
{(char*)"number", T_INT, offsetof(my_native_module_MyNativeClass, number), 0,
|
{(char*)"number", T_INT, offsetof(my_native_module_MyNativeClass, number), 0,
|
||||||
(char*)"custom number"},
|
(char*)"custom number"},
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
my_native_module_MyNativeClass_getfirst(my_native_module_MyNativeClass *self, void *closure)
|
||||||
|
{
|
||||||
|
(void)closure;
|
||||||
|
Py_INCREF(self->first);
|
||||||
|
return self->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
my_native_module_MyNativeClass_setfirst(my_native_module_MyNativeClass *self, PyObject *value, void *closure)
|
||||||
|
{
|
||||||
|
(void)closure;
|
||||||
|
PyObject *tmp;
|
||||||
|
if (value == NULL) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!PyUnicode_Check(value)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"The first attribute value must be a string");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tmp = self->first;
|
||||||
|
Py_INCREF(value);
|
||||||
|
self->first = value;
|
||||||
|
Py_DECREF(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
my_native_module_MyNativeClass_getlast(my_native_module_MyNativeClass *self, void *closure)
|
||||||
|
{
|
||||||
|
(void)closure;
|
||||||
|
Py_INCREF(self->last);
|
||||||
|
return self->last;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
my_native_module_MyNativeClass_setlast(my_native_module_MyNativeClass *self, PyObject *value, void *closure)
|
||||||
|
{
|
||||||
|
(void)closure;
|
||||||
|
PyObject *tmp;
|
||||||
|
if (value == NULL) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!PyUnicode_Check(value)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"The last attribute value must be a string");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tmp = self->last;
|
||||||
|
Py_INCREF(value);
|
||||||
|
self->last = value;
|
||||||
|
Py_DECREF(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
my_native_module_MyNativeClass_name(my_native_module_MyNativeClass *self, PyObject *Py_UNUSED(ignored))
|
my_native_module_MyNativeClass_name(my_native_module_MyNativeClass *self, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
@@ -157,7 +227,7 @@ my_native_module_MyNativeClass_name(my_native_module_MyNativeClass *self, PyObje
|
|||||||
PyErr_SetString(PyExc_AttributeError, "last");
|
PyErr_SetString(PyExc_AttributeError, "last");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return PyUnicode_FromFormat("%S %S", self->first, self->last);
|
return PyUnicode_FromFormat("%S %S %d", self->first, self->last, self->number + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef my_native_module_MyNativeClass_methods[] = {
|
static PyMethodDef my_native_module_MyNativeClass_methods[] = {
|
||||||
@@ -170,6 +240,14 @@ static PyMethodDef my_native_module_MyNativeClass_methods[] = {
|
|||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static PyGetSetDef my_native_module_MyNativeClass_getsetters[] = {
|
||||||
|
{(char *)"first", (getter) my_native_module_MyNativeClass_getfirst, (setter) my_native_module_MyNativeClass_setfirst,
|
||||||
|
(char *)"first name", NULL},
|
||||||
|
{(char *)"last", (getter) my_native_module_MyNativeClass_getlast, (setter) my_native_module_MyNativeClass_setlast,
|
||||||
|
(char *)"last name", NULL},
|
||||||
|
{NULL} /* Sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
static PyTypeObject my_native_module_MyNativeClassType = {
|
static PyTypeObject my_native_module_MyNativeClassType = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
PyVarObject_HEAD_INIT(NULL, 0)
|
||||||
};
|
};
|
||||||
@@ -259,15 +337,69 @@ my_native_module_MyDerivedNativeClass_init(my_native_module_MyDerivedNativeClass
|
|||||||
}
|
}
|
||||||
|
|
||||||
static PyMemberDef my_native_module_MyDerivedNativeClass_members[] = {
|
static PyMemberDef my_native_module_MyDerivedNativeClass_members[] = {
|
||||||
{(char*)"first2", T_OBJECT_EX, offsetof(my_native_module_MyDerivedNativeClass, first2), 0,
|
|
||||||
(char*)"first2 name2"},
|
|
||||||
{(char*)"last2", T_OBJECT_EX, offsetof(my_native_module_MyDerivedNativeClass, last2), 0,
|
|
||||||
(char*)"last2 name2"},
|
|
||||||
{(char*)"number2", T_INT, offsetof(my_native_module_MyDerivedNativeClass, number2), 0,
|
{(char*)"number2", T_INT, offsetof(my_native_module_MyDerivedNativeClass, number2), 0,
|
||||||
(char*)"custom number2"},
|
(char*)"custom number2"},
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
my_native_module_MyDerivedNativeClass_getfirst2(my_native_module_MyDerivedNativeClass *self, void *closure)
|
||||||
|
{
|
||||||
|
(void)closure;
|
||||||
|
Py_INCREF(self->first2);
|
||||||
|
return self->first2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
my_native_module_MyDerivedNativeClass_setfirst2(my_native_module_MyDerivedNativeClass *self, PyObject *value, void *closure)
|
||||||
|
{
|
||||||
|
(void)closure;
|
||||||
|
PyObject *tmp;
|
||||||
|
if (value == NULL) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Cannot delete the first2 attribute");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!PyUnicode_Check(value)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"The first2 attribute value must be a string");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tmp = self->first2;
|
||||||
|
Py_INCREF(value);
|
||||||
|
self->first2 = value;
|
||||||
|
Py_DECREF(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
my_native_module_MyDerivedNativeClass_getlast2(my_native_module_MyDerivedNativeClass *self, void *closure)
|
||||||
|
{
|
||||||
|
(void)closure;
|
||||||
|
Py_INCREF(self->last2);
|
||||||
|
return self->last2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
my_native_module_MyDerivedNativeClass_setlast2(my_native_module_MyDerivedNativeClass *self, PyObject *value, void *closure)
|
||||||
|
{
|
||||||
|
(void)closure;
|
||||||
|
PyObject *tmp;
|
||||||
|
if (value == NULL) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Cannot delete the last2 attribute");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!PyUnicode_Check(value)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"The last2 attribute value must be a string");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tmp = self->last2;
|
||||||
|
Py_INCREF(value);
|
||||||
|
self->last2 = value;
|
||||||
|
Py_DECREF(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
my_native_module_MyDerivedNativeClass_name2(my_native_module_MyDerivedNativeClass *self, PyObject *Py_UNUSED(ignored))
|
my_native_module_MyDerivedNativeClass_name2(my_native_module_MyDerivedNativeClass *self, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
@@ -287,9 +419,19 @@ my_native_module_MyDerivedNativeClass_name2(my_native_module_MyDerivedNativeClas
|
|||||||
PyErr_SetString(PyExc_AttributeError, "last2");
|
PyErr_SetString(PyExc_AttributeError, "last2");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return PyUnicode_FromFormat("%S %S %S %S", self->base.first, self->base.last, self->first2, self->last2);
|
return PyUnicode_FromFormat("%S %S %d %S %S %d",
|
||||||
|
self->base.first, self->base.last, self->base.number + 1,
|
||||||
|
self->first2, self->last2, self->number2 + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyGetSetDef my_native_module_MyDerivedNativeClass_getsetters[] = {
|
||||||
|
{(char *)"first2", (getter) my_native_module_MyDerivedNativeClass_getfirst2, (setter) my_native_module_MyDerivedNativeClass_setfirst2,
|
||||||
|
(char *)"first2 name", NULL},
|
||||||
|
{(char *)"last2", (getter) my_native_module_MyDerivedNativeClass_getlast2, (setter) my_native_module_MyDerivedNativeClass_setlast2,
|
||||||
|
(char *)"last2 name", NULL},
|
||||||
|
{NULL} /* Sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
static PyMethodDef my_native_module_MyDerivedNativeClass_methods[] = {
|
static PyMethodDef my_native_module_MyDerivedNativeClass_methods[] = {
|
||||||
{
|
{
|
||||||
"name2",
|
"name2",
|
||||||
@@ -369,6 +511,7 @@ main(int argc, char *argv[])
|
|||||||
my_native_module_MyNativeClassType.tp_clear = (inquiry) my_native_module_MyNativeClass_clear;
|
my_native_module_MyNativeClassType.tp_clear = (inquiry) my_native_module_MyNativeClass_clear;
|
||||||
my_native_module_MyNativeClassType.tp_members = my_native_module_MyNativeClass_members;
|
my_native_module_MyNativeClassType.tp_members = my_native_module_MyNativeClass_members;
|
||||||
my_native_module_MyNativeClassType.tp_methods = my_native_module_MyNativeClass_methods;
|
my_native_module_MyNativeClassType.tp_methods = my_native_module_MyNativeClass_methods;
|
||||||
|
my_native_module_MyNativeClassType.tp_getset = my_native_module_MyNativeClass_getsetters;
|
||||||
|
|
||||||
my_native_module_MyDerivedNativeClassType.tp_name = "my_native_module.MyDerivedNativeClass";
|
my_native_module_MyDerivedNativeClassType.tp_name = "my_native_module.MyDerivedNativeClass";
|
||||||
my_native_module_MyDerivedNativeClassType.tp_doc = "My native class";
|
my_native_module_MyDerivedNativeClassType.tp_doc = "My native class";
|
||||||
@@ -382,6 +525,7 @@ main(int argc, char *argv[])
|
|||||||
my_native_module_MyDerivedNativeClassType.tp_clear = (inquiry) my_native_module_MyDerivedNativeClass_clear;
|
my_native_module_MyDerivedNativeClassType.tp_clear = (inquiry) my_native_module_MyDerivedNativeClass_clear;
|
||||||
my_native_module_MyDerivedNativeClassType.tp_members = my_native_module_MyDerivedNativeClass_members;
|
my_native_module_MyDerivedNativeClassType.tp_members = my_native_module_MyDerivedNativeClass_members;
|
||||||
my_native_module_MyDerivedNativeClassType.tp_methods = my_native_module_MyDerivedNativeClass_methods;
|
my_native_module_MyDerivedNativeClassType.tp_methods = my_native_module_MyDerivedNativeClass_methods;
|
||||||
|
my_native_module_MyDerivedNativeClassType.tp_getset = my_native_module_MyDerivedNativeClass_getsetters;
|
||||||
|
|
||||||
PyImport_AppendInittab("my_native_module", &my_native_module_init_func);
|
PyImport_AppendInittab("my_native_module", &my_native_module_init_func);
|
||||||
Py_Initialize();
|
Py_Initialize();
|
||||||
|
|||||||
Reference in New Issue
Block a user