Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 04c8107

Browse files
authored
Merge pull request #23358 from anntzer/extension-init-types
Shorten/clarify definition of extension types.
2 parents 4f9ac38 + 8491746 commit 04c8107

File tree

5 files changed

+158
-230
lines changed

5 files changed

+158
-230
lines changed

src/_backend_agg_wrapper.cpp

Lines changed: 30 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ typedef struct
1212
Py_ssize_t suboffsets[3];
1313
} PyRendererAgg;
1414

15+
static PyTypeObject PyRendererAggType;
16+
1517
typedef struct
1618
{
1719
PyObject_HEAD
@@ -21,6 +23,8 @@ typedef struct
2123
Py_ssize_t suboffsets[3];
2224
} PyBufferRegion;
2325

26+
static PyTypeObject PyBufferRegionType;
27+
2428

2529
/**********************************************************************
2630
* BufferRegion
@@ -114,9 +118,7 @@ int PyBufferRegion_get_buffer(PyBufferRegion *self, Py_buffer *buf, int flags)
114118
return 1;
115119
}
116120

117-
static PyTypeObject PyBufferRegionType;
118-
119-
static PyTypeObject *PyBufferRegion_init_type(PyObject *m, PyTypeObject *type)
121+
static PyTypeObject *PyBufferRegion_init_type()
120122
{
121123
static PyMethodDef methods[] = {
122124
{ "to_string", (PyCFunction)PyBufferRegion_to_string, METH_NOARGS, NULL },
@@ -128,26 +130,17 @@ static PyTypeObject *PyBufferRegion_init_type(PyObject *m, PyTypeObject *type)
128130
};
129131

130132
static PyBufferProcs buffer_procs;
131-
memset(&buffer_procs, 0, sizeof(PyBufferProcs));
132133
buffer_procs.bf_getbuffer = (getbufferproc)PyBufferRegion_get_buffer;
133134

134-
memset(type, 0, sizeof(PyTypeObject));
135-
type->tp_name = "matplotlib.backends._backend_agg.BufferRegion";
136-
type->tp_basicsize = sizeof(PyBufferRegion);
137-
type->tp_dealloc = (destructor)PyBufferRegion_dealloc;
138-
type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
139-
type->tp_methods = methods;
140-
type->tp_new = PyBufferRegion_new;
141-
type->tp_as_buffer = &buffer_procs;
142-
143-
if (PyType_Ready(type) < 0) {
144-
return NULL;
145-
}
146-
147-
/* Don't need to add to module, since you can't create buffer
148-
regions directly from Python */
135+
PyBufferRegionType.tp_name = "matplotlib.backends._backend_agg.BufferRegion";
136+
PyBufferRegionType.tp_basicsize = sizeof(PyBufferRegion);
137+
PyBufferRegionType.tp_dealloc = (destructor)PyBufferRegion_dealloc;
138+
PyBufferRegionType.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
139+
PyBufferRegionType.tp_methods = methods;
140+
PyBufferRegionType.tp_new = PyBufferRegion_new;
141+
PyBufferRegionType.tp_as_buffer = &buffer_procs;
149142

150-
return type;
143+
return &PyBufferRegionType;
151144
}
152145

153146
/**********************************************************************
@@ -592,9 +585,7 @@ static PyObject *PyRendererAgg_restore_region(PyRendererAgg *self, PyObject *arg
592585
Py_RETURN_NONE;
593586
}
594587

595-
PyTypeObject PyRendererAggType;
596-
597-
static PyTypeObject *PyRendererAgg_init_type(PyObject *m, PyTypeObject *type)
588+
static PyTypeObject *PyRendererAgg_init_type()
598589
{
599590
static PyMethodDef methods[] = {
600591
{"draw_path", (PyCFunction)PyRendererAgg_draw_path, METH_VARARGS, NULL},
@@ -614,28 +605,18 @@ static PyTypeObject *PyRendererAgg_init_type(PyObject *m, PyTypeObject *type)
614605
};
615606

616607
static PyBufferProcs buffer_procs;
617-
memset(&buffer_procs, 0, sizeof(PyBufferProcs));
618608
buffer_procs.bf_getbuffer = (getbufferproc)PyRendererAgg_get_buffer;
619609

620-
memset(type, 0, sizeof(PyTypeObject));
621-
type->tp_name = "matplotlib.backends._backend_agg.RendererAgg";
622-
type->tp_basicsize = sizeof(PyRendererAgg);
623-
type->tp_dealloc = (destructor)PyRendererAgg_dealloc;
624-
type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
625-
type->tp_methods = methods;
626-
type->tp_init = (initproc)PyRendererAgg_init;
627-
type->tp_new = PyRendererAgg_new;
628-
type->tp_as_buffer = &buffer_procs;
629-
630-
if (PyType_Ready(type) < 0) {
631-
return NULL;
632-
}
610+
PyRendererAggType.tp_name = "matplotlib.backends._backend_agg.RendererAgg";
611+
PyRendererAggType.tp_basicsize = sizeof(PyRendererAgg);
612+
PyRendererAggType.tp_dealloc = (destructor)PyRendererAgg_dealloc;
613+
PyRendererAggType.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
614+
PyRendererAggType.tp_methods = methods;
615+
PyRendererAggType.tp_init = (initproc)PyRendererAgg_init;
616+
PyRendererAggType.tp_new = PyRendererAgg_new;
617+
PyRendererAggType.tp_as_buffer = &buffer_procs;
633618

634-
if (PyModule_AddObject(m, "RendererAgg", (PyObject *)type)) {
635-
return NULL;
636-
}
637-
638-
return type;
619+
return &PyRendererAggType;
639620
}
640621

641622
static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "_backend_agg" };
@@ -644,26 +625,16 @@ static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "_backend_agg" };
644625

645626
PyMODINIT_FUNC PyInit__backend_agg(void)
646627
{
647-
PyObject *m;
648-
649628
import_array();
650-
651-
m = PyModule_Create(&moduledef);
652-
653-
if (m == NULL) {
654-
return NULL;
655-
}
656-
657-
if (!PyRendererAgg_init_type(m, &PyRendererAggType)) {
658-
Py_DECREF(m);
659-
return NULL;
660-
}
661-
662-
if (!PyBufferRegion_init_type(m, &PyBufferRegionType)) {
663-
Py_DECREF(m);
629+
PyObject *m;
630+
if (!(m = PyModule_Create(&moduledef))
631+
|| prepare_and_add_type(PyRendererAgg_init_type(), m)
632+
// BufferRegion is not constructible from Python, thus not added to the module.
633+
|| PyType_Ready(PyBufferRegion_init_type())
634+
) {
635+
Py_XDECREF(m);
664636
return NULL;
665637
}
666-
667638
return m;
668639
}
669640

src/_macosx.m

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <ApplicationServices/ApplicationServices.h>
88
#include <sys/socket.h>
99
#include <Python.h>
10+
#include "mplutils.h"
1011

1112
#ifndef PYPY
1213
/* Remove this once Python is fixed: https://bugs.python.org/issue23237 */
@@ -1920,23 +1921,16 @@ static void context_cleanup(const void* info)
19201921

19211922
PyObject* PyInit__macosx(void)
19221923
{
1923-
if (PyType_Ready(&FigureCanvasType) < 0
1924-
|| PyType_Ready(&FigureManagerType) < 0
1925-
|| PyType_Ready(&NavigationToolbar2Type) < 0
1926-
|| PyType_Ready(&TimerType) < 0)
1927-
return NULL;
1928-
1929-
PyObject *module = PyModule_Create(&moduledef);
1930-
if (!module) {
1924+
PyObject *m;
1925+
if (!(m = PyModule_Create(&moduledef))
1926+
|| prepare_and_add_type(&FigureCanvasType, m)
1927+
|| prepare_and_add_type(&FigureManagerType, m)
1928+
|| prepare_and_add_type(&NavigationToolbar2Type, m)
1929+
|| prepare_and_add_type(&TimerType, m)) {
1930+
Py_XDECREF(m);
19311931
return NULL;
19321932
}
1933-
1934-
PyModule_AddObject(module, "FigureCanvas", (PyObject*) &FigureCanvasType);
1935-
PyModule_AddObject(module, "FigureManager", (PyObject*) &FigureManagerType);
1936-
PyModule_AddObject(module, "NavigationToolbar2", (PyObject*) &NavigationToolbar2Type);
1937-
PyModule_AddObject(module, "Timer", (PyObject*) &TimerType);
1938-
1939-
return module;
1933+
return m;
19401934
}
19411935

19421936
#pragma GCC visibility pop

src/ft2font_wrapper.cpp

Lines changed: 40 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ typedef struct
3333
Py_ssize_t suboffsets[2];
3434
} PyFT2Image;
3535

36+
static PyTypeObject PyFT2ImageType;
37+
3638
static PyObject *PyFT2Image_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3739
{
3840
PyFT2Image *self;
@@ -121,9 +123,7 @@ static int PyFT2Image_get_buffer(PyFT2Image *self, Py_buffer *buf, int flags)
121123
return 1;
122124
}
123125

124-
static PyTypeObject PyFT2ImageType;
125-
126-
static PyTypeObject *PyFT2Image_init_type(PyObject *m, PyTypeObject *type)
126+
static PyTypeObject* PyFT2Image_init_type()
127127
{
128128
static PyMethodDef methods[] = {
129129
{"draw_rect", (PyCFunction)PyFT2Image_draw_rect, METH_VARARGS, PyFT2Image_draw_rect__doc__},
@@ -132,28 +132,18 @@ static PyTypeObject *PyFT2Image_init_type(PyObject *m, PyTypeObject *type)
132132
};
133133

134134
static PyBufferProcs buffer_procs;
135-
memset(&buffer_procs, 0, sizeof(PyBufferProcs));
136135
buffer_procs.bf_getbuffer = (getbufferproc)PyFT2Image_get_buffer;
137136

138-
memset(type, 0, sizeof(PyTypeObject));
139-
type->tp_name = "matplotlib.ft2font.FT2Image";
140-
type->tp_basicsize = sizeof(PyFT2Image);
141-
type->tp_dealloc = (destructor)PyFT2Image_dealloc;
142-
type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
143-
type->tp_methods = methods;
144-
type->tp_new = PyFT2Image_new;
145-
type->tp_init = (initproc)PyFT2Image_init;
146-
type->tp_as_buffer = &buffer_procs;
147-
148-
if (PyType_Ready(type) < 0) {
149-
return NULL;
150-
}
137+
PyFT2ImageType.tp_name = "matplotlib.ft2font.FT2Image";
138+
PyFT2ImageType.tp_basicsize = sizeof(PyFT2Image);
139+
PyFT2ImageType.tp_dealloc = (destructor)PyFT2Image_dealloc;
140+
PyFT2ImageType.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
141+
PyFT2ImageType.tp_methods = methods;
142+
PyFT2ImageType.tp_new = PyFT2Image_new;
143+
PyFT2ImageType.tp_init = (initproc)PyFT2Image_init;
144+
PyFT2ImageType.tp_as_buffer = &buffer_procs;
151145

152-
if (PyModule_AddObject(m, "FT2Image", (PyObject *)type)) {
153-
return NULL;
154-
}
155-
156-
return type;
146+
return &PyFT2ImageType;
157147
}
158148

159149
/**********************************************************************
@@ -217,7 +207,7 @@ static PyObject *PyGlyph_get_bbox(PyGlyph *self, void *closure)
217207
"llll", self->bbox.xMin, self->bbox.yMin, self->bbox.xMax, self->bbox.yMax);
218208
}
219209

220-
static PyTypeObject *PyGlyph_init_type(PyObject *m, PyTypeObject *type)
210+
static PyTypeObject *PyGlyph_init_type()
221211
{
222212
static PyMemberDef members[] = {
223213
{(char *)"width", T_LONG, offsetof(PyGlyph, width), READONLY, (char *)""},
@@ -237,22 +227,14 @@ static PyTypeObject *PyGlyph_init_type(PyObject *m, PyTypeObject *type)
237227
{NULL}
238228
};
239229

240-
memset(type, 0, sizeof(PyTypeObject));
241-
type->tp_name = "matplotlib.ft2font.Glyph";
242-
type->tp_basicsize = sizeof(PyGlyph);
243-
type->tp_dealloc = (destructor)PyGlyph_dealloc;
244-
type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
245-
type->tp_members = members;
246-
type->tp_getset = getset;
247-
248-
if (PyType_Ready(type) < 0) {
249-
return NULL;
250-
}
251-
252-
/* Don't need to add to module, since you can't create glyphs
253-
directly from Python */
230+
PyGlyphType.tp_name = "matplotlib.ft2font.Glyph";
231+
PyGlyphType.tp_basicsize = sizeof(PyGlyph);
232+
PyGlyphType.tp_dealloc = (destructor)PyGlyph_dealloc;
233+
PyGlyphType.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
234+
PyGlyphType.tp_members = members;
235+
PyGlyphType.tp_getset = getset;
254236

255-
return type;
237+
return &PyGlyphType;
256238
}
257239

258240
/**********************************************************************
@@ -270,6 +252,8 @@ typedef struct
270252
Py_ssize_t suboffsets[2];
271253
} PyFT2Font;
272254

255+
static PyTypeObject PyFT2FontType;
256+
273257
static unsigned long read_from_file_callback(FT_Stream stream,
274258
unsigned long offset,
275259
unsigned char *buffer,
@@ -317,8 +301,6 @@ static void close_file_callback(FT_Stream stream)
317301
PyErr_Restore(type, value, traceback);
318302
}
319303

320-
static PyTypeObject PyFT2FontType;
321-
322304
static PyObject *PyFT2Font_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
323305
{
324306
PyFT2Font *self;
@@ -1448,7 +1430,7 @@ static int PyFT2Font_get_buffer(PyFT2Font *self, Py_buffer *buf, int flags)
14481430
return 1;
14491431
}
14501432

1451-
static PyTypeObject *PyFT2Font_init_type(PyObject *m, PyTypeObject *type)
1433+
static PyTypeObject *PyFT2Font_init_type()
14521434
{
14531435
static PyGetSetDef getset[] = {
14541436
{(char *)"postscript_name", (getter)PyFT2Font_postscript_name, NULL, NULL, NULL},
@@ -1503,30 +1485,20 @@ static PyTypeObject *PyFT2Font_init_type(PyObject *m, PyTypeObject *type)
15031485
};
15041486

15051487
static PyBufferProcs buffer_procs;
1506-
memset(&buffer_procs, 0, sizeof(PyBufferProcs));
15071488
buffer_procs.bf_getbuffer = (getbufferproc)PyFT2Font_get_buffer;
15081489

1509-
memset(type, 0, sizeof(PyTypeObject));
1510-
type->tp_name = "matplotlib.ft2font.FT2Font";
1511-
type->tp_doc = PyFT2Font_init__doc__;
1512-
type->tp_basicsize = sizeof(PyFT2Font);
1513-
type->tp_dealloc = (destructor)PyFT2Font_dealloc;
1514-
type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
1515-
type->tp_methods = methods;
1516-
type->tp_getset = getset;
1517-
type->tp_new = PyFT2Font_new;
1518-
type->tp_init = (initproc)PyFT2Font_init;
1519-
type->tp_as_buffer = &buffer_procs;
1520-
1521-
if (PyType_Ready(type) < 0) {
1522-
return NULL;
1523-
}
1524-
1525-
if (PyModule_AddObject(m, "FT2Font", (PyObject *)type)) {
1526-
return NULL;
1527-
}
1490+
PyFT2FontType.tp_name = "matplotlib.ft2font.FT2Font";
1491+
PyFT2FontType.tp_doc = PyFT2Font_init__doc__;
1492+
PyFT2FontType.tp_basicsize = sizeof(PyFT2Font);
1493+
PyFT2FontType.tp_dealloc = (destructor)PyFT2Font_dealloc;
1494+
PyFT2FontType.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
1495+
PyFT2FontType.tp_methods = methods;
1496+
PyFT2FontType.tp_getset = getset;
1497+
PyFT2FontType.tp_new = PyFT2Font_new;
1498+
PyFT2FontType.tp_init = (initproc)PyFT2Font_init;
1499+
PyFT2FontType.tp_as_buffer = &buffer_procs;
15281500

1529-
return type;
1501+
return &PyFT2FontType;
15301502
}
15311503

15321504
static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "ft2font" };
@@ -1546,11 +1518,12 @@ PyMODINIT_FUNC PyInit_ft2font(void)
15461518
FT_Library_Version(_ft2Library, &major, &minor, &patch);
15471519
snprintf(version_string, sizeof(version_string), "%d.%d.%d", major, minor, patch);
15481520

1549-
PyObject *m = PyModule_Create(&moduledef);
1550-
if (!m ||
1551-
!PyFT2Image_init_type(m, &PyFT2ImageType) ||
1552-
!PyGlyph_init_type(m, &PyGlyphType) ||
1553-
!PyFT2Font_init_type(m, &PyFT2FontType) ||
1521+
PyObject *m;
1522+
if (!(m = PyModule_Create(&moduledef)) ||
1523+
prepare_and_add_type(PyFT2Image_init_type(), m) ||
1524+
prepare_and_add_type(PyFT2Font_init_type(), m) ||
1525+
// Glyph is not constructible from Python, thus not added to the module.
1526+
PyType_Ready(PyGlyph_init_type()) ||
15541527
PyModule_AddStringConstant(m, "__freetype_version__", version_string) ||
15551528
PyModule_AddStringConstant(m, "__freetype_build_type__", STRINGIFY(FREETYPE_BUILD_TYPE)) ||
15561529
PyModule_AddIntConstant(m, "SCALABLE", FT_FACE_FLAG_SCALABLE) ||

src/mplutils.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,20 @@ enum {
4646

4747
const size_t NUM_VERTICES[] = { 1, 1, 1, 2, 3, 1 };
4848

49+
inline int prepare_and_add_type(PyTypeObject *type, PyObject *module)
50+
{
51+
if (PyType_Ready(type)) {
52+
return -1;
53+
}
54+
char const* ptr = strrchr(type->tp_name, '.');
55+
if (!ptr) {
56+
PyErr_SetString(PyExc_ValueError, "tp_name should be a qualified name");
57+
return -1;
58+
}
59+
if (PyModule_AddObject(module, ptr + 1, (PyObject *)type)) {
60+
return -1;
61+
}
62+
return 0;
63+
}
64+
4965
#endif

0 commit comments

Comments
 (0)